P1501 [国家集训队]Tree II(LCT)

给出一棵树,请你支持:

1)删边。

2)加边。

3)路径点权+c。

4)路径点权乘c。

5)询问路径点权和。

答案对51061取模。

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
const int mod=51061;
typedef long long ll;
ll ch[maxn][2],fa[maxn],sz[maxn],val[maxn],sum[maxn],rev[maxn];
ll add[maxn],mul[maxn];
void clear (int x) {
	ch[x][0]=ch[x][1]=fa[x]=sz[x]=val[x]=sum[x]=rev[x]=add[x]=0;
	mul[x]=1;
}
int get (int x) {
	return ch[fa[x]][1]==x?1:0;
}
int isRoot (int x) {
	clear(0);
	return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void pushup (int x) {
	clear(0);
	sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;sz[x]%=mod;
	sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+val[x])%mod;
}
void pushdown (int x) {
	clear(0);
	if (mul[x]!=1) {
		if (ch[x][0]) {
			mul[ch[x][0]]=(mul[ch[x][0]]*mul[x])%mod;
			val[ch[x][0]]=(val[ch[x][0]]*mul[x])%mod;
			sum[ch[x][0]]=(sum[ch[x][0]]*mul[x])%mod;
			add[ch[x][0]]=(add[ch[x][0]]*mul[x])%mod;
		}
		if (ch[x][1]) {
			mul[ch[x][1]]=(mul[ch[x][1]]*mul[x])%mod;
			val[ch[x][1]]=(val[ch[x][1]]*mul[x])%mod;
			sum[ch[x][1]]=(sum[ch[x][1]]*mul[x])%mod;
			add[ch[x][1]]=(add[ch[x][1]]*mul[x])%mod;
		}
		mul[x]=1;
	}
	if (add[x]) {
		if (ch[x][0]) {
			add[ch[x][0]]=(add[ch[x][0]]+add[x])%mod;
			val[ch[x][0]]=(val[ch[x][0]]+add[x])%mod;
			sum[ch[x][0]]=(sum[ch[x][0]]+add[x]*sz[ch[x][0]]%mod)%mod;
		}
		if (ch[x][1]) {
			add[ch[x][1]]=(add[ch[x][1]]+add[x])%mod;
			val[ch[x][1]]=(val[ch[x][1]]+add[x])%mod;
			sum[ch[x][1]]=(sum[ch[x][1]]+add[x]*sz[ch[x][1]]%mod)%mod;
		}
		add[x]=0;
	}
	if (rev[x]) {
		if (ch[x][0]) {
			rev[ch[x][0]]^=1;
			swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
		}
		if (ch[x][1]) {
			rev[ch[x][1]]^=1;
			swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
		}
		rev[x]=0;
	}
}
void update (int x) {
	if (!isRoot(x)) update(fa[x]);
	pushdown(x);
}
void rotate (int x) {
	int y=fa[x],z=fa[y],chx=get(x),chy=get(y);
	fa[x]=z;
	if (!isRoot(y)) ch[z][chy]=x;
	ch[y][chx]=ch[x][chx^1];
	fa[ch[x][chx^1]]=y;
	ch[x][chx^1]=y;
	fa[y]=x;
	pushup(y);
	pushup(x);
	pushup(z);
}
void splay (int x) {
	update(x);
	for (int f=fa[x];f=fa[x],!isRoot(x);rotate(x)) {
		if (!isRoot(f)) rotate(get(x)==get(f)?f:x);
	}
}
void access (int x) {
	for (int f=0;x;f=x,x=fa[x]) {
		splay(x);
		ch[x][1]=f;
		pushup(x);
	}
}
void makeRoot (int x) {
	access(x);
	splay(x);
	swap(ch[x][0],ch[x][1]);
	rev[x]^=1;
} 
int find (int x) {
	access(x);
	splay(x);
	while (ch[x][0]) x=ch[x][0];
	splay(x);
	return x;
}
int n,q;
int main () {
	scanf("%d%d",&n,&q);
	for (int i=1;i<=n;i++) val[i]=1,pushup(i);
	for (int i=1;i<n;i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		if (find(u)!=find(v)) {
			makeRoot(u);
			fa[u]=v;
		} 
	}
	while (q--) {
		char op;
		int u,v;
		cin>>op>>u>>v;
		if (op=='+') {
			ll c;
			scanf("%lld",&c);
			makeRoot(u);
			access(v);
			splay(v);
			val[v]=(val[v]+c)%mod;
			sum[v]=(sum[v]+sz[v]*c%mod)%mod;
			add[v]=(add[v]+c)%mod;
		}
		else if (op=='-') {
			makeRoot(u);
			access(v);
			splay(v);
			if (ch[v][0]==u&&!ch[u][1]) ch[v][0]=fa[u]=0;
			scanf("%d%d",&u,&v);
			if (find(u)!=find(v)) {
				makeRoot(u);fa[u]=v;
			}
		}
		else if (op=='*') {
			ll c;
			scanf("%lld",&c);
			c%=mod;
			makeRoot(u);
			access(v);
			splay(v);
			val[v]=(val[v]*c)%mod;
			sum[v]=(sum[v]*c)%mod;
			mul[v]=(mul[v]*c)%mod;
			//add[v]=(add[v]*c)%mod;
		}
		else if (op=='/') {
			makeRoot(u);
			access(v);
			splay(v);
			sum[v]%=mod;
			printf("%lld
",sum[v]);
		}
	}
}
原文地址:https://www.cnblogs.com/zhanglichen/p/15116838.html