8pts求调(only AC on #11)
查看原帖
8pts求调(only AC on #11)
553501
可爱的小棉羊楼主2023/11/7 16:48
#include<bits/stdc++.h>
using namespace std;

const int N=2e5+5;
struct node{
	int l,r,sum,maxx,minn;
	bool tag;
}v[N*4];
int n,cnt;
int rn[N],rnk[N],hea[N],size[N],dfn[N],dep[N],top[N];
int nxt[N*2],head[N],to[N*2],w[N*2],fa[N],dw[N],m;
void addedge(int u,int v,int r,int s){
	nxt[s]=head[u];
	to[s]=v;
	w[s]=r;
	head[u]=s;
}
void dfs1(int step){
	size[step]=1;
	for(int i=head[step];i;i=nxt[i]){
		int v=to[i];
		//cout<<v<<endl;
		if(dep[v])continue;
		dep[v]=dep[step]+1;
		fa[v]=step;
		dw[v]=w[i];
		if(i>=n)rn[i-n+1]=v;
		else rn[i]=v;
		dfs1(v);
		size[step]+=size[v];
		if(size[v]>size[hea[step]])hea[step]=v;
	}
}
void dfs2(int step,int too){
	cnt++;
	dfn[cnt]=step;
	rnk[step]=cnt;
	top[step]=too;
	if(hea[step]!=0)dfs2(hea[step],too);
	for(int i=head[step];i;i=nxt[i]){
		int v=to[i];
		if(hea[step]==v||v==fa[step])continue;
		dfs2(v,v);
	}
}
//树链剖分 
void push_up(int rt){
	v[rt].sum=v[rt<<1].sum+v[rt<<1|1].sum; 
	v[rt].maxx=max(v[rt<<1].maxx,v[rt<<1|1].maxx);
	v[rt].minn=max(v[rt<<1].minn,v[rt<<1|1].minn);
}
void push_tag(int rt){
	v[rt].tag^=1;
	v[rt].maxx=-v[rt].maxx;
	v[rt].minn=-v[rt].minn;
	v[rt].sum=-v[rt].sum;
	swap(v[rt].maxx,v[rt].minn);
	
}
void push_down(int rt){
	if(v[rt].tag==0)return;
	push_tag(rt<<1);
	push_tag(rt<<1|1);
	v[rt].tag=0;
}
void build(int rt,int l,int r){
	v[rt].l=l;
	v[rt].r=r;
	if(l==r){
		v[rt].sum=v[rt].minn=v[rt].maxx=dw[dfn[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	push_up(rt);
}
void upda(int rt,int k,int w){
	if(v[rt].l==v[rt].r){
		v[rt].sum=v[rt].maxx=v[rt].minn=w;
		return;
	}
	push_down(rt);
	int mid=(v[rt].l+v[rt].r)>>1;
	if(k<=mid)upda(rt<<1,k,w);
	else upda(rt<<1|1,k,w);
	push_up(rt);
}
void upda2(int rt,int l,int r){
	if(l<=v[rt].l&&v[rt].r<=r){
		push_tag(rt);
		return;
	}
	push_down(rt);
	int mid=(v[rt].l+v[rt].r)>>1;
	if(l<=mid)upda2(rt<<1,l,r);
	if(r>=mid+1)upda2(rt<<1|1,l,r);
	push_up(rt);
}
int gsum(int rt,int l,int r){
	if(l<=v[rt].l&&v[rt].r<=r)return v[rt].sum;
	push_down(rt);
	int s=0,mid=(v[rt].l+v[rt].r)>>1;
	if(l<=mid)s+=gsum(rt<<1,l,r);
	if(r>=mid+1)s+=gsum(rt<<1|1,l,r);
	return s;
}
int gmax(int rt,int l,int r){
	if(l<=v[rt].l&&v[rt].r<=r)return v[rt].maxx;
	push_down(rt);
	int maxx=-1e9,mid=(v[rt].l+v[rt].r)>>1;
	if(l<=mid)maxx=max(maxx,gmax(rt<<1,l,r));
	if(r>=mid+1)maxx=max(maxx,gmax(rt<<1|1,l,r));
	return maxx;
}
int gmin(int rt,int l,int r){
	if(l<=v[rt].l&&v[rt].r<=r)return v[rt].minn;
	push_down(rt);
	int minn=0x3f3f3f3f,mid=(v[rt].l+v[rt].r)>>1;
	if(l<=mid)minn=min(minn,gmin(rt<<1,l,r));
	if(r>=mid+1)minn=min(minn,gmin(rt<<1|1,l,r));
	return minn;
}
void update(int u,int v){
	int x=u,y=v; 
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		upda2(1,rnk[top[x]],x);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	if(x!=y)upda2(1,rnk[x]+1,rnk[y]);
}
int qsum(int u,int v){
	int res=0,x=u,y=v;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		res+=gsum(1,rnk[top[x]],rnk[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	if(x!=y)res+=gsum(1,rnk[x]+1,rnk[y]);
	return res;
}
int qmax(int u,int v){
	int res=-114514,x=u,y=v;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		res=max(res,gmax(1,rnk[top[x]],rnk[x]));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	if(x!=y)res=max(res,gmax(1,rnk[x]+1,rnk[y]));
	return res;
}
int qmin(int u,int v){
	int res=114514,x=u,y=v;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		res=min(res,gmin(1,rnk[top[x]],rnk[x]));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	if(x!=y)res=min(res,gmin(1,rnk[x]+1,rnk[y]));
	return res;
}
int main(){
	cin>>n;
	//memset(nxt,0x3f3f3f3f,sizeof(nxt));
	for(int i=1;i<n;i++){
		int u,v,w;
		cin>>u>>v>>w;
		u++;
		v++;
		addedge(u,v,w,i);
		addedge(v,u,w,i+n-1);
	}
	dep[1]=1;
	dfs1(1);
	dfs2(1,1);
	cin>>m;
	build(1,1,n);
	while(m--){
		string opt;
		cin>>opt;
		if(opt=="C"){
			int c,w;
			cin>>c>>w;
			upda(1,rnk[rn[c]],w);
		}else if(opt=="N"){
			int u,v;
			cin>>u>>v;
			u++;
			v++;
			update(u,v);
		}else if(opt=="SUM"){
			int u,v;
			cin>>u>>v;
			u++;
			v++;
			cout<<qsum(u,v)<<endl;
		}else if(opt=="MAX"){
			int u,v;
			cin>>u>>v;
			u++;
			v++;
			cout<<qmax(u,v)<<endl;
		}else{
			int u,v;
			cin>>u>>v;
			u++;
			v++;
			cout<<qmin(u,v)<<endl;
		}
	}
	//for(int i=1;i<=n;i++)cout<<dfn[i]<<" ";
} 
//3 0 1 1 1 2 2
2023/11/7 16:48
加载中...