蒟蒻树剖求调
查看原帖
蒟蒻树剖求调
576448
aulive楼主2023/9/29 14:32

rt

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5;
int n,u[maxn+5],v[maxn+5],w,fa[maxn+5],dept[maxn+5],mem[maxn+5],val[maxn+5],top[maxn+5],son[maxn+5],size[maxn+5],ys[maxn+5],tot,x,y;
struct node{
	int lef,rig,minn,maxx,tag,sum;
}tree[maxn<<2|1];
string opt;
vector <int> rood[maxn+5];
vector <int> rood_val[maxn+5];
void dfs1(int now,int fat){
	fa[now]=fat;
	dept[now]=dept[fat]+1;
	size[now]=1;
	for(int i=0;i<rood[now].size();i++){
		int to=rood[now][i];
		if(to==fat)continue;
		val[to]=rood_val[now][i];
		dfs1(to,now);
		size[now]+=size[to];
		if(size[to]>size[son[now]])son[now]=to;
	}
}
void dfs2(int now,int topf){
	top[now]=topf;
	ys[now]=++tot;
	mem[tot]=val[now];
	if(!son[now])return;
	dfs2(son[now],topf);
	for(int i=0;i<rood[now].size();i++){
		int to=rood[now][i];
		if(top[to])continue;
		dfs2(to,to);
	}
}
void pushup(int now){
	tree[now].maxx=max(tree[now<<1].maxx,tree[now<<1|1].maxx);
	tree[now].minn=min(tree[now<<1].minn,tree[now<<1|1].minn);
	tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
}
void build(int now,int lef,int rig){
	tree[now].lef=lef,tree[now].rig=rig;
	if(lef==rig){
		tree[now].maxx=tree[now].minn=tree[now].sum=mem[lef];
		return;
	}
	int mid=lef+rig>>1;
	build(now<<1,lef,mid);
	build(now<<1|1,mid+1,rig);
	pushup(now);
}
void pushdown(int now){
	if(tree[now].tag){
		tree[now<<1].tag^=1;
		tree[now<<1|1].tag^=1;
		swap(tree[now<<1].maxx,tree[now<<1].minn);
		swap(tree[now<<1|1].maxx,tree[now<<1|1].minn);
		tree[now<<1].maxx*=-1;
		tree[now<<1].minn*=-1;
		tree[now<<1].sum*=-1;
		tree[now<<1|1].maxx*=-1;
		tree[now<<1|1].minn*=-1;
		tree[now<<1|1].sum*=-1;
		tree[now].tag=0;
	}
}
void modify(int now,int to,int aim){
	if(tree[now].lef==tree[now].rig){
		tree[now].maxx=tree[now].sum=tree[now].minn=aim;
		return;
	}
	pushdown(now);
	int mid=tree[now].lef+tree[now].rig>>1;
	if(to<=mid){
		modify(now<<1,to,aim);
	}else{
		modify(now<<1|1,to,aim);
	}
	pushup(now);
}
void modify_tag(int now,int lef,int rig){
	if(lef<=tree[now].lef&&tree[now].rig<=rig){
		tree[now].tag^=1;
		swap(tree[now].maxx,tree[now].minn);
		tree[now].minn*=-1;
		tree[now].maxx*=-1;
		tree[now].sum*=-1;
		return;
	}
	pushdown(now);
	int mid=tree[now].lef+tree[now].rig>>1;
	if(lef<=mid){
		modify_tag(now<<1,lef,rig);
	}
	if(mid<rig){
		modify_tag(now<<1|1,lef,rig);
	}
	pushup(now);
}
int query_maxx(int now,int lef,int rig){
	if(lef<=tree[now].lef&&tree[now].rig<=rig){
		return tree[now].maxx;
	}
	pushdown(now);
	int mid=tree[now].lef+tree[now].rig>>1;
	int res=-1001;
	if(lef<=mid){
		res=query_maxx(now<<1,lef,rig);
	}
	if(mid<rig){
		res=max(res,query_maxx(now<<1|1,lef,rig));
	}
//	pushup(now);
	return res;
}
int query_minn(int now,int lef,int rig){
	if(lef<=tree[now].lef&&tree[now].rig<=rig){
		return tree[now].maxx;
	}
	pushdown(now);
	int mid=tree[now].lef+tree[now].rig>>1;
	int res=1001;
	if(lef<=mid){
		res=query_minn(now<<1,lef,rig);
	}
	if(mid<rig){
		res=min(res,query_minn(now<<1|1,lef,rig));
	}
//	pushup(now);
	return res;
}
int query_sum(int now,int lef,int rig){
	if(lef<=tree[now].lef&&tree[now].rig<=rig){
		return tree[now].maxx;
	}
	pushdown(now);
	int mid=tree[now].lef+tree[now].rig>>1;
	int res=0;
	if(lef<=mid){
		res=query_sum(now<<1,lef,rig);
	}
	if(mid<rig){
		res+=query_sum(now<<1|1,lef,rig);
	}
//	pushup(now);
	return res;
}
void tree_modify_tag(int x,int y){
	while(top[x]!=top[y]){
		if(dept[top[x]]<dept[top[y]])swap(x,y);
		modify_tag(1,ys[top[x]],ys[x]);
		x=fa[top[x]];
	}
	if(dept[x]<dept[y])swap(x,y);
	modify_tag(1,ys[y]+1,ys[x]);
}
int tree_query_minn(int x,int y){
	int res=1001;
	while(top[x]!=top[y]){
		if(dept[top[x]]<dept[top[y]])swap(x,y);
		res=min(res,query_minn(1,ys[top[x]],ys[x]));
		x=fa[top[x]];
	}
	if(dept[x]<dept[y])swap(x,y);
	return min(res,query_minn(1,ys[y]+1,ys[x]));
}
int tree_query_maxx(int x,int y){
	int res=-1001;
	while(top[x]!=top[y]){
		if(dept[top[x]]<dept[top[y]])swap(x,y);
		res=max(res,query_maxx(1,ys[top[x]],ys[x]));
		x=fa[top[x]];
	}
	if(dept[x]<dept[y])swap(x,y);
	return max(res,query_maxx(1,ys[y]+1,ys[x]));
}
int tree_query_sum(int x,int y){
	int res=0;
	while(top[x]!=top[y]){
		if(dept[top[x]]<dept[top[y]])swap(x,y);
		res+=query_sum(1,ys[top[x]],ys[x]);
		x=fa[top[x]];
	}
	if(dept[x]<dept[y])swap(x,y);
	return res+query_sum(1,ys[y]+1,ys[x]);
}
signed main(){
	cin>>n;
	for(int i=1;i<n;i++){
		cin>>u[i]>>v[i]>>w;
		u[i]++,v[i]++;
		rood[u[i]].push_back(v[i]);
		rood[v[i]].push_back(u[i]);
		rood_val[u[i]].push_back(w);
		rood_val[v[i]].push_back(w);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,tot);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>opt>>x>>y;
		if(opt[0]=='C'){
			int fw=u[x];
			if(dept[u[x]]<dept[v[x]]){
				fw=v[x];
			}
			modify(1,fw,y);
		}else{
			x++,y++;
			if(opt[0]=='N'){
				tree_modify_tag(x,y);
			}else{
				if(opt[0]=='S'){
					cout<<tree_query_sum(x,y)<<"\n";
				}else{
					if(opt[1]=='A'){
						cout<<tree_query_maxx(x,y)<<"\n";
					}else{
						cout<<tree_query_minn(x,y)<<"\n";
					}
				}
			}
		}
	}
	return 0;
}
2023/9/29 14:32
加载中...