树剖求调,悬赏4关
查看原帖
树剖求调,悬赏4关
940678
lhrfc楼主2023/5/1 09:33

如果你帮我调对了,@lhrfc,@luhaoren,@lsxz,@bluesss 会同时关注你

#include <bits/stdc++.h>
using  namespace std;
const int N=1e5+10,inf=0x3f3f3f3f;
struct node{
	int fa,maxson,dep,size,top,id,w;
	vector<int>e;
}tr[N];
int dfn[N],tot=0,edge[N],n,m;
void dfs1(int x,int fa,int dep){
	tr[x].fa=fa,tr[x].dep=dep,tr[x].size=1,tr[x].maxson=0;
	int maxx=-1;
	for(auto it:tr[x].e){
		if(it==fa) continue;
		dfs1(it,x,dep+1);
		tr[x].size+=tr[it].size;
		if(tr[it].size>maxx) maxx=tr[it].size,tr[x].maxson=it;
	}
}
void dfs2(int x,int top){
	tr[x].top=top,dfn[++tot]=tr[x].w,tr[x].id=tot;
	if(!tr[x].maxson) return;
	dfs2(tr[x].maxson,top);
	for(auto it:tr[x].e){
		if(it==tr[x].fa||it==tr[x].maxson) continue;
		dfs2(it,it);
	}
}
class XDS{
public:
	struct node{
		int sum,maxx,minn;
		int l,r;
		bool tag;
	}tr[N*4];
	inline void pushup(int x){
		tr[x].sum=tr[x*2].sum+tr[x*2+1].sum;
		tr[x].maxx=max(tr[x*2].maxx,tr[x*2+1].maxx);
		tr[x].minn=min(tr[x*2].minn,tr[x*2+1].minn);
	}
	inline void pushdown(int x){
		if(tr[x].tag){
			int tmax=tr[x].maxx,tmin=tr[x].minn;
			tr[x].sum=-tr[x].sum,tr[x].maxx=tmin,tr[x].minn=tmax;
			tr[x*2].tag^=1,tr[x*2+1].tag^=1;
			tr[x].tag=0;
		}
	}
	void build(int x,int l,int r){
		tr[x].l=l,tr[x].r=r,tr[x].tag=0;
		if(l==r){
			tr[x].maxx=tr[x].minn=tr[x].sum=dfn[l];
			return;
		}
		int mid=(l+r)/2;
		build(x*2,l,mid),build(x*2+1,mid+1,r);
		pushup(x);
	}
	void change_one(int now,int x,int w){		
		pushdown(now);
		if(tr[now].l==tr[now].r){
			tr[now].maxx=tr[now].minn=tr[now].sum=w;
			return;
		}
		int mid=(tr[now].l+tr[now].r)/2;
		if(x<=mid) change_one(now*2,x,w);
		else change_one(now*2+1,x,w);
		pushup(now);
	}
	int query_max(int x,int l,int r){
		pushdown(x);
		if(tr[x].l>=l&&tr[x].r<=r) return tr[x].maxx;
		int mid=(tr[x].l+tr[x].r)/2,maxx=-inf;
		if(l<=mid) maxx=query_max(x*2,l,r);
		if(r>mid) maxx=max(maxx,query_max(x*2+1,l,r));
		return maxx;
	}
	int query_min(int x,int l,int r){
		pushdown(x);
		if(tr[x].l>=l&&tr[x].r<=r) return tr[x].minn;
		int mid=(tr[x].l+tr[x].r)/2,minn=inf;
		if(l<=mid) minn=query_min(x*2,l,r);
		if(r>mid) minn=min(minn,query_min(x*2+1,l,r));
		return minn;
	}
	int query_sum(int x,int l,int r){
		pushdown(x);
		if(tr[x].l>=l&&tr[x].r<=r) return tr[x].sum;
		int mid=(tr[x].l+tr[x].r)/2,sum=0;
		if(l<=mid) sum=query_sum(x*2,l,r);
		if(r>mid) sum+=query_sum(x*2+1,l,r);
		return sum;
	}
	void change(int x,int l,int r){
		pushdown(x);
		if(tr[x].l>=l&&tr[x].r<=r){
			tr[x].tag^=1;
			return;
		}
		int mid=(tr[x].l+tr[x].r)/2;
		if(l<=mid) change(x*2,l,r);
		if(r>mid) change(x*2+1,l,r);
		pushup(x);
	}
};
XDS xds;
inline void QC(int i,int w){
	xds.change_one(1,tr[edge[i]].id,w);
}
inline void QN(int u,int v){
	while(tr[u].top!=tr[v].top){
		if(tr[tr[u].top].dep<tr[tr[v].top].dep) swap(u,v);
		int t=tr[u].top;
		xds.change(1,tr[t].id,tr[u].id);
		u=tr[t].fa;
	}
	if(tr[u].dep>tr[v].dep) swap(u,v);
	if(u!=v) xds.change(1,tr[u].id+1,tr[v].id);
}
inline int QSUM(int u,int v){
	int ans=0;
	while(tr[u].top!=tr[v].top){
		if(tr[tr[u].top].dep<tr[tr[v].top].dep) swap(u,v);
		int t=tr[u].top;
		ans+=xds.query_sum(1,tr[t].id,tr[u].id);
		u=tr[t].fa;
	}
	if(tr[u].dep>tr[v].dep) swap(u,v);
	if(u!=v) ans+=xds.query_sum(1,tr[u].id+1,tr[v].id);
	return ans;
}

inline int QMAX(int u,int v){
	int maxx=-inf;
	while(tr[u].top!=tr[v].top){
		if(tr[tr[u].top].dep<tr[tr[v].top].dep) swap(u,v);
		int t=tr[u].top;
		maxx=max(maxx,xds.query_max(1,tr[t].id,tr[u].id));
		u=tr[t].fa;
	}
	if(tr[u].dep>tr[v].dep) swap(u,v);
	if(u!=v) maxx=max(maxx,xds.query_max(1,tr[u].id+1,tr[v].id));
	return maxx;
}
inline int QMIN(int u,int v){
	int minn=inf;
	while(tr[u].top!=tr[v].top){
		if(tr[tr[u].top].dep<tr[tr[v].top].dep) swap(u,v);
		int t=tr[u].top;
		minn=min(minn,xds.query_min(1,tr[t].id,tr[u].id));
		u=tr[t].fa;
	}
	if(tr[u].dep>tr[v].dep) swap(u,v);
	if(u!=v) minn=min(minn,xds.query_min(1,tr[u].id+1,tr[v].id));
	return minn;	
}
int main(){
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int u,v,w;
		cin>>u>>v>>w;
		edge[i]=v;
		tr[u].e.push_back(v),tr[v].e.push_back(u);
		tr[v].w=w;
	}
	dfs1(1,1,1);
	dfs2(1,1);
	xds.build(1,1,n);
	cin>>m;
	while(m--){
		string s;
		int a,b;
		cin>>s>>a>>b;
		if(s=="C") QC(a,b);
		if(s=="N") QN(a+1,b+1); 
		if(s=="SUM") cout<<QSUM(a+1,b+1)<<endl;
		if(s=="MAX") cout<<QMAX(a+1,b+1)<<endl;
		if(s=="MIN") cout<<QMIN(a+1,b+1)<<endl;
	}
}
2023/5/1 09:33
加载中...