树剖求调,AC #5 #6 #9,讨论区似乎没有和我一样的错误
查看原帖
树剖求调,AC #5 #6 #9,讨论区似乎没有和我一样的错误
614527
xwh_Marvelous楼主2023/2/24 13:20
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,w[30005],t;
struct Segment{
	#define mid ((l+r)>>1)
	#define lson (x<<1)
	#define rson ((x<<1)+1)
	int a[30005*8],b[30005*8];
	void push_up(int x){
		a[x]=a[lson]+a[rson];
		b[x]=max(b[lson],b[rson]);
	}
	void init(int x,int l,int r){
		if(l==r){
			a[x]=b[x]=w[l];
			return;
		}
		init(lson,l,mid),init(rson,mid+1,r);
		push_up(x);
	}
	void update(int t,int p,int x,int l,int r){
		if(l==r){
			a[x]=b[x]=t;
			return;
		}
		if(p<=mid)update(t,p,lson,l,mid);
		else update(t,p,rson,mid+1,r);
		push_up(x);
	}
	int getsum(int L,int R,int x,int l,int r){
		if(L<=l&&r<=R){
			return a[x];
		}
		int ans=0;
		if(L<=mid)ans+=getsum(L,R,lson,l,mid);
		if(R>mid)ans+=getsum(L,R,rson,mid+1,r);
		return ans;
	}
	int getmax(int L,int R,int x,int l,int r){
		if(L<=l&&r<=R){
			return b[x];
		}
		int ans=INT_MIN;
		if(L<=mid)ans=max(ans,getmax(L,R,lson,l,mid));
		if(R>mid)ans=max(ans,getmax(L,R,rson,mid+1,r));
		return ans;
	}
}hitoi;
struct TreeCut{
	struct edge{int nt,v;}e[30005*3];
	int dep[30005],fa[30005],siz[30005],dfn[30005],top[30005],son[30005],rnk[30005];
	int tot,head[30005];
	int cnt;
	void addedge(int u,int v){
		e[++tot]={head[u],v};
		head[u]=tot;
		e[++tot]={head[v],u};
		head[v]=tot;
	}
	void dfs1(int x){
		son[x]=0;
		siz[x]=1;
		for(int i=head[x];i;i=e[i].nt){
			if(!dep[e[i].v]){
				dep[e[i].v]=dep[x]+1;
				fa[e[i].v]=x;
				dfs1(e[i].v);
				siz[x]+=siz[e[i].v];
				if(siz[e[i].v]>siz[son[x]])son[x]=e[i].v;
			}
		}
	}
	void dfs2(int x,int t){
		top[x]=t;
		dfn[x]=++cnt;
		rnk[cnt]=x;
		if(!son[x])return;
		dfs2(son[x],t);
		for(int i=head[x];i;i=e[i].nt){
			if(e[i].v!=son[x]&&!dfn[e[i].v])dfs2(e[i].v,e[i].v);
		}
	}
	void init(){
		dep[1]=1;
		dfs1(1);
		dfs2(1,1);
		int k[30005];
		for(int i=1;i<=n;i++)k[i]=w[dfn[i]];
		for(int i=1;i<=n;i++)w[i]=k[i];
		hitoi.init(1,1,n);
	}
	void change(int a,int b){
		hitoi.update(b,dfn[a],1,1,n);
	}
	int qsum(int x,int y){
		int ret=0,fx=top[x],fy=top[y];
		while(fx!=fy){
			if(dep[fx]>=dep[fy])ret+=hitoi.getsum(dfn[fx],dfn[x],1,1,n),x=fa[fx];
			else ret+=hitoi.getsum(dfn[fy],dfn[y],1,1,n),y=fa[fy];
			fy=top[y],fx=top[x];
		}
		ret+=hitoi.getsum(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,1,n);
		return ret;
	}
	int qmax(int x,int y){
		int ret=INT_MIN,fx=top[x],fy=top[y];
		while(fx!=fy){
			if(dep[fx]>=dep[fy])ret=max(ret,hitoi.getmax(dfn[fx],dfn[x],1,1,n)),x=fa[fx];
			else ret=max(ret,hitoi.getmax(dfn[fy],dfn[y],1,1,n)),y=fa[fy];
			fy=top[y],fx=top[x];
		}
		ret=max(ret,hitoi.getmax(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,1,n));
		return ret;
	}
}qwq;
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<n;i++){
		int a,b;
		scanf("%lld%lld",&a,&b);
		qwq.addedge(a,b);
	}
	for(int i=1;i<=n;i++)scanf("%lld",w+i);
	qwq.init();
	scanf("%lld",&t);
	while(t--){
		char s[10];
		int a,b;
		scanf("%s%lld%lld",s,&a,&b);
		if(s[1]=='M')printf("%lld\n",qwq.qmax(a,b));
		else if(s[1]=='S')printf("%lld\n",qwq.qsum(a,b));
		else qwq.change(a,b);
	}
	return 0;
} 
2023/2/24 13:20
加载中...