树剖爆0求助
查看原帖
树剖爆0求助
428358
Grisses楼主2022/5/4 08:18
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,tot,cnt,h[100005],len[100005],w[100005],m[100005],top[100005],son[100005],L[100005],DFS[100005],f[100005],U[100005];
struct edge{
	int v,nxt,w,id;
}e[200005];
struct ST{
	struct node{
		int l,r,p,val;
		bool f;
	}c[400005];
	void down(int q){
		if((c[q].p||c[q].f)&&c[q].l!=c[q].r){
			if(c[q].f){
				c[q<<1].f=c[q<<1|1].f=1;
				c[q<<1].p=c[q<<1|1].p=c[q].p;
				c[q<<1].val=c[q].p;
				c[q<<1|1].val=c[q].p;
				c[q].p=c[q].f=0;
			}
			else{
				c[q<<1].p+=c[q].p;
				c[q<<1].val+=c[q].p;
				c[q<<1|1].p+=c[q].p;
				c[q<<1|1].val+=c[q].p;
				c[q].p=0;
			}
		}
	}
	void Build(int q,int l,int r){
		c[q].l=l,c[q].r=r;c[q].f=c[q].p=0;
		if(l==r){c[q].val=w[DFS[l]];return;}
		int mid=l+r>>1;
		Build(q<<1,l,mid);
		Build(q<<1|1,mid+1,r);
		c[q].val=max(c[q<<1].val,c[q<<1|1].val);
	}
	void Cover(int q,int l,int r,int x){
		if(l<=c[q].l&&c[q].r<=r){
			c[q].f=1;
			c[q].p=x;
			c[q].val=x;
			return;
		}
		down(q);
		int mid=c[q].l+c[q].r>>1;
		if(l<=mid)Cover(q<<1,l,r,x);
		if(mid<r)Cover(q<<1|1,l,r,x);
		c[q].val=max(c[q<<1].val,c[q<<1|1].val);
	}
	void Cover(int u,int v,int x){
		int fu=top[u],fv=top[v];
		while(fu!=fv){
			if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
//			cerr<<u<<' '<<fu<<endl<<v<<' '<<fv<<endl;
			Cover(1,L[fu],L[u],x);
			u=f[fu];
			fu=top[u];
		}
		if(len[u]>len[v])swap(u,v);
		Cover(1,L[u],L[v],x);
	}
	void Change(int q,int x,int y){
		if(c[q].l==c[q].r){c[q].val=y;return;}
		down(q);
		int mid=c[q].l+c[q].r>>1;
		if(x<=mid)Change(q<<1,x,y);
		else Change(q<<1|1,x,y);
		c[q].val=max(c[q<<1].val,c[q<<1|1].val);
	}
	void Add(int q,int l,int r,int x){
		if(l<=c[q].l&&c[q].r<=r){
			c[q].p+=x;
			c[q].val+=x;
			return;
		}
		down(q);
		int mid=c[q].l+c[q].r>>1;
		if(l<=mid)Add(q<<1,l,r,x);
		if(mid<r)Add(q<<1|1,l,r,x);
		c[q].val=max(c[q<<1].val,c[q<<1|1].val);
	}
	void Add(int u,int v,int k){
		int fu=top[u],fv=top[v];
		while(fu!=fv){
			if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
			Add(1,L[fu],L[u],k);
			u=f[fu];
			fu=top[u];
		}
		if(len[u]>len[v])swap(u,v);
		Add(1,L[u],L[v],k);
	}
	int Getmax(int q,int l,int r){
		if(l<=c[q].l&&c[q].r<=r)return c[q].val;
		down(q);
		int mid=c[q].l+c[q].r>>1,res=0;
		if(l<=mid)res=max(res,Getmax(q<<1,l,r));
		if(mid<r)res=max(res,Getmax(q<<1|1,l,r));
		return res;
	}
	int Getmax(int u,int v){
		int fu=top[u],fv=top[v],res=0;
		while(fu!=fv){
			if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
			res=max(res,Getmax(1,L[fu],L[u]));
//			cerr<<"+++"<<res<<endl;
			u=f[fu];
			fu=top[u];
		}
		if(len[u]>len[v])swap(u,v);
		res=max(res,Getmax(1,L[u],L[v]));
//		cerr<<"+++"<<res<<endl;
		return res;
	}
}T;
inline void adde(int u,int v,int w,int id){
	e[++cnt].nxt=h[u];
	h[u]=cnt;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].id=id;
}
void dfs(int x){
	m[x]=1;
	for(int i=h[x];i;i=e[i].nxt){
		if(e[i].v==f[x])continue;
		len[e[i].v]=len[x]+1;
		f[e[i].v]=x;
		w[e[i].v]=e[i].w;
		U[e[i].id]=e[i].v;
		dfs(e[i].v);
		m[x]+=m[e[i].v];
		if(m[e[i].v]>m[son[x]])son[x]=e[i].v;
	}
}
void dfs1(int x,int tp){
	top[x]=tp;
	L[x]=++tot;
	DFS[tot]=x;
	if(son[x])dfs1(son[x],tp);
	for(int i=h[x];i;i=e[i].nxt){
		if(e[i].v==f[x]||e[i].v==son[x])continue;
		dfs1(e[i].v,e[i].v);
	}
}
signed main()
{
//	freopen("P4315_1.in","r",stdin);
//	freopen("P4315_1.ans","w",stdout);
	scanf("%lld",&n);
	for(int i=2,x,y,z;i<=n;i++){
		scanf("%lld%lld%lld",&x,&y,&z);
		adde(x,y,z,i-1);
		adde(y,x,z,i-1);
	}
	dfs(1);
	dfs1(1,1);
//	cerr<<"U:"<<endl;
//	for(int i=1;i<n;i++)cerr<<U[i]<<' ';
//	cerr<<endl;
//	cerr<<"Son:"<<endl;
//	for(int i=1;i<=n;i++)cerr<<DFS[i]<<' ';
//	cerr<<endl;
	T.Build(1,1,tot);
	string s;
	int k,u,v,w;
	while(cin>>s){
		if(s=="Change"){
			scanf("%lld%lld",&k,&w);
			T.Change(1,L[U[k]],w);
		}
		else if(s=="Cover"){
			scanf("%lld%lld%lld",&u,&v,&w);
			T.Cover(u,v,w);
			T.Change(1,1,0);
		}
		else if(s=="Add"){
			scanf("%lld%lld%lld",&u,&v,&w);
			T.Add(u,v,w);
			T.Change(1,1,0);
		}
		else if(s=="Max"){
			scanf("%lld%lld",&u,&v);
			printf("%lld\n",T.Getmax(u,v));
		}
		else break;
	}
	return 0;
}
2022/5/4 08:18
加载中...