树链剖分求助!
查看原帖
树链剖分求助!
174806
xbb2楼主2022/8/24 22:16
/*	Name:
	Copyright:[Xcoi]
	Author:xbb2
	Date:
	Description:*/
#include<bits/stdc++.h>
using namespace std;
const int N=6e4+10;
const int mod=309133584;
const int inf=INT_MAX;
int n,q;
int a[N],rnk[N],dfn[N],fa[N],top[N],son[N],siz[N],dep[N];
int to[N],nxt[N],first[N],cnt=0,tot=0;
inline void add(int u,int v){
	to[++cnt]=v;
	nxt[cnt]=first[u];
	first[u]=cnt;
}
struct tree_max{
	short d[N*4],b[N*4];
	inline void build(int s,int t,int p){
		if(s==t){d[p]=b[p]=a[rnk[s]];return ;}
		int m=((s+t)>>1);
		build(s,m,p*2),build(m+1,t,p*2+1);
		d[p]=max(d[p*2],d[p*2+1]);
		b[p]=b[p*2]+b[p*2+1];
	}
	inline void update(int l,int r,int s,int t,int p,int c){
		if(l<=s&&t<=r){d[p]=b[p]=c;return ;}
		int m=((s+t)>>1);
		if(l<=m)update(l,r,s,m,p*2,c);
		else	update(l,r,m+1,t,p*2+1,c);
		d[p]=max(d[p*2],d[p*2+1]);
		b[p]=b[p*2]+b[p*2+1];
	}
	inline int query_max(int l,int r,int s,int t,int p){
		if(l<=s&&t<=r)return d[p];
		int m=((s+t)>>1),ans=-inf;
		if(l<=m)ans=max(ans,query_max(l,r,s,m,p*2));
		if(m<r)	ans=max(ans,query_max(l,r,m+1,t,p*2+1));
		return ans;
	}
	inline int query_sum(int l,int r,int s,int t,int p){
		if(l<=s&&t<=r)return b[p];
		int m=((s+t)>>1),ans=0;
		if(l<=m)ans+=query_sum(l,r,s,m,p*2);
		if(m<r)	ans+=query_sum(l,r,m+1,t,p*2+1);
		return ans;
	}
}T;
void dfs1(int x){
	siz[x]=1;
	for(int i=first[x];i;i=nxt[i]){
		int y=to[i];
		if(!dep[y]){
			dep[y]=dep[x]+1;
			fa[y]=x;dfs1(y);
			siz[x]+=siz[y];
			if(siz[y]>siz[son[x]])son[x]=y;
		}
	}
}
void dfs2(int x,int t){
	top[x]=t,dfn[x]=++tot,rnk[tot]=x;
	if(son[x]==0)return ;dfs2(son[x],t);
	for(int i=first[x];i;i=nxt[i]){
		int y=to[i];
		if(son[x]!=y&&fa[x]!=y)dfs2(y,y);
	}
}
int getmax(int x,int y){
	int ans=-inf,fx=top[x],fy=top[y];
	while(fx!=fy){
		if(dep[fx]>=dep[fy])
			ans=max(ans,T.query_max(dfn[fx],dfn[x],1,n,1)),x=fa[x];
		else
			ans=max(ans,T.query_max(dfn[fy],dfn[y],1,n,1)),y=fa[y];
		fx=top[x],fy=top[y];
	}
	if(dfn[x]<dfn[y])
		ans=max(ans,T.query_max(dfn[x],dfn[y],1,n,1));
	else
		ans=max(ans,T.query_max(dfn[y],dfn[x],1,n,1));
	return ans;
}
int getsum(int x,int y){
	int ans=0,fx=top[x],fy=top[y];
	while(fx!=fy){
		if(dep[fx]>=dep[fy])
			ans+=T.query_sum(dfn[fx],dfn[x],1,n,1),x=fa[x];
		else
			ans+=T.query_sum(dfn[fy],dfn[y],1,n,1),y=fa[y];
		fx=top[x],fy=top[y];
	}
	if(dfn[x]<dfn[y])
		ans+=T.query_sum(dfn[x],dfn[y],1,n,1);
	else
		ans+=T.query_sum(dfn[y],dfn[x],1,n,1);
	return ans;
}
int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
	}
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	dep[1]=1;dfs1(1),dfs2(1,1);
	T.build(1,n,1);cin>>q;
	for(int i=1;i<=q;i++){
		string str;int x,y;
		cin>>str;scanf("%d%d",&x,&y);
		if(str=="CHANGE") T.update(x,x,1,n,1,y);
		if(str=="QMAX") printf("%d\n",getmax(x,y));
		if(str=="QSUM") printf("%d\n",getsum(x,y));
	}
	return 0;
}

2022/8/24 22:16
加载中...