蒟蒻求助 LCT
查看原帖
蒟蒻求助 LCT
128591
Refined_heart楼主2021/7/27 22:23

不知道为啥把 link 里面的 findroot 去掉就对了……没想通为啥

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
const int mod=51061;
inline int Add(int x,int y){return (x+y)%mod;}
inline int Mul(int x,int y){return 1ll*x*y%mod;}
#define gc() getchar()
inline int read(){
	int s=0,w=1;
	char ch=gc();
	while(!isdigit(ch)){
		if(ch=='-')w=-1;
		ch=gc();
	}
	while(isdigit(ch)){
		s=s*10-'0'+ch;
		ch=getchar();
	}
	return s*w;
}
struct LinkCutTree{
	bool rev[N];
	int ch[N][2],f[N],mul[N],add[N];
	int sum[N],val[N],siz[N],st[N];
	inline void pushup(int x){sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x];sum[x]%=mod;siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
	inline void pushr(int x){int t=ch[x][0];ch[x][0]=ch[x][1];ch[x][1]=t;rev[x]^=1;}
	inline void pushm(int x,int v){sum[x]=Mul(sum[x],v);val[x]=Mul(val[x],v);mul[x]=Mul(mul[x],v);add[x]=Mul(add[x],v);}
	inline void pusha(int x,int v){sum[x]=Add(sum[x],Mul(siz[x],v));add[x]=Add(add[x],v);val[x]=Add(val[x],v);}
	inline void pushdown(int x){
		if(mul[x]!=1){
			pushm(ch[x][0],mul[x]);
			pushm(ch[x][1],mul[x]);
			mul[x]=1;
		}
		if(add[x]){
			pusha(ch[x][0],add[x]);
			pusha(ch[x][1],add[x]);
			add[x]=0;
		}
		if(rev[x]){
			if(ch[x][0])pushr(ch[x][0]);
			if(ch[x][1])pushr(ch[x][1]);
			rev[x]^=1;
		}
	}
	inline bool nroot(int x){return ch[f[x]][1]==x||ch[f[x]][0]==x;}
	void rotate(int x){
		int y=f[x],z=f[y],k=(ch[y][1]==x),w=ch[x][k^1];
		if(nroot(y))ch[z][ch[z][1]==y]=x;ch[x][k^1]=y;ch[y][k]=w;
		if(w)f[w]=y;f[y]=x;f[x]=z;pushup(y);pushup(x);
	}
	void splay(int x){
		int y=x,z=0;
		st[++z]=y;
		while(nroot(y)) st[++z]=y=f[y];
		while(z) pushdown(st[z--]);
		while(nroot(x)){
			y=f[x];z=f[y];
			if(nroot(y))rotate((ch[y][0]==x)^(ch[z][0]==y)?x:y);
			rotate(x);
		}
		pushup(x);
	}
	inline void access(int x){
		for(int y=0;x;y=x,x=f[x]){
			splay(x);ch[x][1]=y;pushup(x); 
		}
	}
	inline void makeroot(int x){
		access(x);
		splay(x);
		pushr(x);
	}
	int findroot(int x){
		access(x);splay(x);
		while(ch[x][0])pushdown(x),x=ch[x][0];
		splay(x);return x;
	}
	void split(int x,int y){
		makeroot(x);
		access(y);
		splay(y);
	}
	void link(int x,int y){
		makeroot(x);
		//if(findroot(y)!=x)
      f[x]=y;
	}
	void cut(int x,int y){
		makeroot(x);
		if(findroot(y)==x&&f[y]==x&&!ch[y][0]){
			f[y]=ch[x][1]=0;
			pushup(x);
		}
	}
	void changeadd(int x,int y,int v){
		split(x,y);
		pusha(y,v);
	}
	void changemul(int x,int y,int v){
		split(x,y);
		pushm(y,v);
	}
	int query(int x,int y){
		split(x,y);
		return sum[y];
	}
}T;
int n,q;
int main(){
	n=read();q=read();
	for(int i=1;i<n;++i){
		int u=read(),v=read();
		T.link(u,v);
	}
	for(int i=1;i<=n;++i)T.mul[i]=T.val[i]=T.siz[i]=1;
	for(int kkk=1;kkk<=q;++kkk){
		char opt;
		cin>>opt;
		if(opt=='+'){
			int u=read();
			int v=read();
			int c=read();
			T.changeadd(u,v,c);
		} 
		else if(opt=='-'){
			int u1=read();
			int v1=read();
			int u2=read();
			int v2=read();
			T.cut(u1,v1);
			T.link(u2,v2); 
		}
		else if(opt=='*'){
			int u=read();
			int v=read();
			int c=read();
			T.changemul(u,v,c); 
		}
		else {
			int u=read(),v=read();
			printf("%d\n",T.query(u,v));
		}
	}
	return 0;
} 
2021/7/27 22:23
加载中...