萌新求助,真的刚学 LCT ,5 pts
查看原帖
萌新求助,真的刚学 LCT ,5 pts
60864
tiger2005楼主2021/1/13 23:18
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
// Splay
const int MAXN = 1e5 + 10;
const long long Md = 51061;
int val[MAXN],cc[MAXN][2],fa[MAXN],siz[MAXN];
bool rev[MAXN];
long long adt[MAXN],ans[MAXN],mul[MAXN];
inline void pushUp(int x){
	if(x==0)	return;
	ans[x]=(ans[cc[x][0]]+ans[cc[x][1]]+val[x])%Md;
	siz[x]=siz[cc[x][0]]+siz[cc[x][1]]+1;
}
inline void revSplay(int x){
	swap(cc[x][0],cc[x][1]),rev[x]^=1;
}
inline void addSplay(int x,int v){
	(adt[x]+=v)%=Md;(ans[x]+=1ll*v*siz[x])%=Md;(val[x]+=v)%=Md;
}
inline void mulSplay(int x,int v){
	(adt[x]*=v)%=Md;(mul[x]*=v)%=Md;(val[x]*=v)%=Md;(ans[x]*=v)%=Md;
}
inline void pushDown(int x){
	if(mul[x]!=1){
		if(cc[x][0])	mulSplay(cc[x][0],mul[x]);
		if(cc[x][1])	mulSplay(cc[x][1],mul[x]);
		mul[x]=1;
	}
	if(adt[x]){
		if(cc[x][0])	addSplay(cc[x][0],adt[x]);
		if(cc[x][1])	addSplay(cc[x][1],adt[x]);
		adt[x]=0;
	}
	if(rev[x]){
		if(cc[x][0])	revSplay(cc[x][0]);
		if(cc[x][1])	revSplay(cc[x][1]);
		rev[x]=false;
	}
}
// Start - nroot
inline bool nroot(int x){
	return cc[fa[x]][0]==x || cc[fa[x]][1]==x;
}
// End - nroot
inline void rtt(int x){
	int y=fa[x],z=fa[y],k=(cc[y][1]==x);
	if(z && nroot(y))
		cc[z][cc[z][1]==y]=x;
	fa[x]=z;
	cc[y][k]=cc[x][!k];
	if(cc[x][!k])	fa[cc[x][!k]]=y;
	cc[x][!k]=y;fa[y]=x;
	pushUp(y);pushUp(x);
}
vector<int> stk;
inline void splay(int x,int g=0){
	int q=x;stk.push_back(q);
	while(nroot(q))	stk.push_back(q=fa[q]);
	while(!stk.empty())	pushDown(stk.back()),stk.pop_back();
	while(nroot(x)){
		int y=fa[x],z=fa[y];
		if(nroot(y))
			((cc[z][0]==y)^(cc[y][0]==x))?rtt(x):rtt(y);
		rtt(x);
	}
	pushUp(x);
}
// Link Cut Tree
inline void access(int x){
	for(int y=0;x;x=fa[y=x])
		splay(x),cc[x][1]=y,pushUp(x);
}
inline void makeRoot(int x){
	access(x);splay(x);revSplay(x);
}
inline int findRoot(int x){
	access(x);splay(x);
	while(cc[x][0])	pushDown(x),x=cc[x][0];
	splay(x);return x;
}
inline void split(int x,int y){
	makeRoot(x);access(y);splay(y);
}
//inline void link(int x,int y){
//	makeRoot(x);
//	if(findRoot(y)==x)	return;
//	fa[x]=y;pushUp(y);
//}
//inline void cut(int x,int y){
//	makeRoot(x);
//	if(findRoot(y)!=x || fa[y]!=x || cc[y][0])	return;
//	fa[y]=cc[x][1]=0;pushUp(x);
//}
inline void link(int x,int y){
	makeRoot(x);fa[x]=y;pushUp(y);
}
inline void cut(int x,int y){
	split(x,y);fa[x]=cc[y][0]=0;
}
int N,M;
int main(){
	scanf("%d%d",&N,&M);
	for(int i=1;i<=N;i++)	mul[i]=siz[i]=val[i]=ans[i]=1;
	for(int i=1,x,y;i<N;i++){
		scanf("%d%d",&x,&y);link(x,y);
	}
	int x,y,z;
	char typ[2];
	while(M--){
		scanf(" %s",typ);
		if(typ[0]=='+'){
			scanf("%d%d%d",&x,&y,&z);
			split(x,y);addSplay(y,z);
		}
		else if(typ[0]=='-'){
			scanf("%d%d",&x,&y);cut(x,y);
			scanf("%d%d",&x,&y);link(x,y);
		}
		else if(typ[0]=='*'){
			scanf("%d%d%d",&x,&y,&z);
			split(x,y);mulSplay(y,z);
		}
		else{
			scanf("%d%d",&x,&y);
			split(x,y);printf("%lld\n",ans[y]);
		}
	}
	return 0;
}

情况是只 AC 了最后一个点。

2021/1/13 23:18
加载中...