现在的位置: 首页 > 综合 > 正文

1984: 月下“毛景树”

2018年04月24日 ⁄ 综合 ⁄ 共 3756字 ⁄ 字号 评论关闭
#include<iostream>
#include<cstdlib>
#include<cstdio>
#define N 100001
#define inf 0x7fffffff
using namespace std;
int n,cnt=1,sz,head[N],deep[N],size[N],pos[N],belong[N],fa[N][17],id[N];
struct edge{int to,next,v;}e[N<<1];
struct seg{int l,r,mx,c,a;}node[N<<2];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void insert(int u,int v,int w){
	e[++cnt]=(edge){v,head[u],w};head[u]=cnt;
	e[++cnt]=(edge){u,head[v],w};head[v]=cnt;
}
int lca(int x,int y){
	if(deep[x]<deep[y])swap(x,y);
	int d=deep[x]-deep[y];
	for(int i=0;i<=16;i++)
		if((1<<i)&d)x=fa[x][i];
	for(int i=16;i>=0;i--)
		if(fa[x][i]!=fa[y][i])
			x=fa[x][i],y=fa[y][i];
	if(x==y)return x;
	else return fa[x][0];
}
void pushdown(int k){
	if(node[k].l==node[k].r)return;
	if(node[k].c!=-1){
		node[k<<1].a=node[k<<1|1].a=0;
		node[k<<1].c=node[k<<1|1].c=node[k<<1].mx=node[k<<1|1].mx=node[k].c;
		node[k].c=-1;
	}
	if(node[k].a){
		node[k<<1].mx+=node[k].a;node[k<<1|1].mx+=node[k].a;
		if(node[k<<1].c!=-1)node[k<<1].c+=node[k].a;
			else node[k<<1].a+=node[k].a;
		if(node[k<<1|1].c!=-1)node[k<<1|1].c+=node[k].a;
			else node[k<<1|1].a+=node[k].a;
		node[k].a=0;
	}
}
void build(int k,int l,int r){
	node[k]=(seg){l,r,0,-1,0};
	if(l==r)return;
	int mid=(l+r)>>1;
	build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
void pushup(int k){node[k].mx=max(node[k<<1].mx,node[k<<1|1].mx);}
void change(int k,int x,int y,int v){
	pushdown(k);
	int l=node[k].l,r=node[k].r;
	if(l==x&&r==y){node[k].mx=node[k].c=v;return;}
	int mid=(l+r)>>1;
	if(y<=mid)change(k<<1,x,y,v);
	else if(x>mid)change(k<<1|1,x,y,v);
	else{change(k<<1,x,mid,v);change(k<<1|1,mid+1,y,v);}
	pushup(k);
}
void add(int k,int x,int y,int v){
	pushdown(k);
	int l=node[k].l,r=node[k].r;
	if(l==x&&r==y){node[k].mx+=v;node[k].a=v;return;}
	int mid=(l+r)>>1;
	if(y<=mid)add(k<<1,x,y,v);
	else if(x>mid)add(k<<1|1,x,y,v);
	else{add(k<<1,x,mid,v);add(k<<1|1,mid+1,y,v);}
	pushup(k);	
}
int ask(int k,int x,int y){
	pushdown(k);
	int l=node[k].l,r=node[k].r;
	if(l==x&&r==y)return node[k].mx;
	int mid=(l+r)>>1;
	if(y<=mid)return ask(k<<1,x,y);
	else if(x>mid)return ask(k<<1|1,x,y);
	else return max(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
}
//////////////////////////////////////////
void solvechange(int x,int f,int v){
	while(belong[x]!=belong[f]){
		change(1,pos[belong[x]],pos[x],v);
		x=fa[belong[x]][0];
	}
	if(pos[f]+1<=pos[x])change(1,pos[f]+1,pos[x],v);
}
void solveadd(int x,int f,int v){
	while(belong[x]!=belong[f]){
		add(1,pos[belong[x]],pos[x],v);
		x=fa[belong[x]][0];
	}
	if(pos[f]+1<=pos[x])add(1,pos[f]+1,pos[x],v);	
}
int solveask(int x,int f){
	int ans=-inf;
	while(belong[x]!=belong[f]){
		ans=max(ans,ask(1,pos[belong[x]],pos[x]));
		x=fa[belong[x]][0];
	}
	if(pos[f]+1<=pos[x])ans=max(ans,ask(1,pos[f]+1,pos[x]));
	return ans;
}
void solve(){
	char s[10];
	int u,v,w,f;
	while(1){
		scanf("%s",s);
		switch(s[1]){
			case 't':return;break;
			case 'a':u=read();v=read();f=lca(u,v);printf("%d\n",max(solveask(u,f),solveask(v,f)));break;
			case 'o':u=read();v=read();w=read();f=lca(u,v);solvechange(u,f,w);solvechange(v,f,w);break;
			case 'h':u=read();w=read();change(1,pos[id[u]],pos[id[u]],w);break;
			case 'd':u=read();v=read();w=read();f=lca(u,v);solveadd(u,f,w);solveadd(v,f,w);break;
		}
	}
}
void dfs1(int x,int father){
	size[x]=1;
	for(int i=1;i<=16;i++)
		if((1<<i)<=deep[x])
			fa[x][i]=fa[fa[x][i-1]][i-1];
		else break;
	for(int i=head[x];i;i=e[i].next){
		if(e[i].to==father)continue;
		deep[e[i].to]=deep[x]+1;
		fa[e[i].to][0]=x;
		dfs1(e[i].to,x);
		size[x]+=size[e[i].to];
	}
}
void dfs2(int x,int chain){
	belong[x]=chain;
	pos[x]=++sz;
	int k=0;
	for(int i=head[x];i;i=e[i].next)
		if(deep[x]<deep[e[i].to]&&size[e[i].to]>size[k])
			k=e[i].to;
		else if(deep[x]>deep[e[i].to]){id[i>>1]=x;add(1,pos[x],pos[x],e[i].v);}
	if(!k)return;
	dfs2(k,chain);
	for(int i=head[x];i;i=e[i].next)
		if(deep[x]<deep[e[i].to]&&k!=e[i].to)
			dfs2(e[i].to,e[i].to);
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read(),w=read();
		insert(u,v,w);
	}
	build(1,1,n);
	dfs1(1,0);dfs2(1,1);
	solve();
	return 0;
} 

抱歉!评论已关闭.