[国家集训队]Tree II

link

我再次探索了我个人智商的最低值。我真他妈的是个傻逼,纯纯的傻逼。

题目没有什么好说的,都是lct的基本操作。而让我调了差不多三个小时的是我的一行脑残代码,具体情况见求助帖,改了之后就过了。

他奶奶的就这么一个低级得不能再低级的错误我竟然花了三个小时来调。郁闷至极。

#include<cstdio>
//#define zczc
#define int long long
const int N=100010;
const int mod=51061;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline void swap(int &s1,int &s2){
	int s3=s1;s1=s2;s2=s3;return;
}

int m,n;

#define lc t[x].ch[0]
#define rc t[x].ch[1]
struct node{
	int f,ch[2],sum,size,data,lazy,add,mul;
}t[N];
inline void pushup(int x){
	t[x].size=t[lc].size+t[rc].size+1;
	t[x].sum=(t[lc].sum+t[rc].sum+t[x].data)%mod;
}
inline void pushnow(int x,int add,int mul){
	if(!x)return;
	t[x].data=(t[x].data*mul+add)%mod;
	t[x].add=(t[x].add*mul+add)%mod;
	t[x].mul=t[x].mul*mul%mod;
	t[x].sum=(t[x].sum*mul+t[x].size*add)%mod;
}
inline void pushlazy(int x){
	t[x].lazy^=1;
	swap(lc,rc);
}
inline void pushdown(int x){
	if(t[x].lazy){
		t[x].lazy=false;
		pushlazy(lc);pushlazy(rc);
	}
	if(t[x].add||t[x].mul){
		pushnow(lc,t[x].add,t[x].mul);
		pushnow(rc,t[x].add,t[x].mul);
		t[x].add=0;
		if(t[x].mul!=0)t[x].mul=1;
		pushup(x);
	}
}
inline bool check(int x){
	int fa=t[x].f;
	return t[fa].ch[0]==x||t[fa].ch[1]==x;
}
inline void rotate(int x){
	int y=t[x].f;int z=t[y].f;bool kk=t[y].ch[1]==x;
	if(check(y))t[z].ch[t[z].ch[1]==y]=x;
	if(t[x].ch[!kk])t[t[x].ch[!kk]].f=y;
	t[x].f=z;t[y].f=x;
	t[y].ch[kk]=t[x].ch[!kk];
	t[x].ch[!kk]=y;
	pushup(y);pushup(x);
}
inline void pushdd(int x){
	if(check(x))pushdd(t[x].f);
	pushdown(x);
}
inline void splay(int x){
	pushdd(x);
	while(check(x)){
		int y=t[x].f;int z=t[y].f;
		if(check(y))(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
		rotate(x);
	}
}
inline void access(int x){
	for(int y=0;x;x=t[y=x].f){
		splay(x);rc=y;
		if(y)t[y].f=x;
		pushup(x);
	}
}
inline void makeroot(int x){
	access(x);splay(x);
	pushlazy(x);
}
inline int findroot(int x){
	access(x);splay(x);
	while(true){
		pushdown(x);
		if(lc)x=lc;
		else return x;
	}
}
inline void makelink(int x,int y){
	makeroot(x);
	if(findroot(y)^x)t[x].f=y;
}
inline void cut(int x,int y){
	makeroot(x);access(y);splay(y);
	if(t[y].ch[0]^x)return;
	t[y].ch[0]=0;t[x].f=0;pushup(y);
}
inline void change(int x,int y,int add,int mul){
	makeroot(x);
	access(y);splay(y);
	pushnow(y,add,mul);
}
inline void work(int x,int y){
	makeroot(x);
	access(y);splay(y);
	printf("%lld\n",t[y].sum);
}
#undef lc
#undef rc

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	
	read(m);read(n);int s1,s2,s3,s4;char w[10];
	for(int i=1;i<=m;i++)t[i].size=t[i].mul=t[i].data=t[i].sum=1;
	for(int i=1;i<m;i++){
		read(s1);read(s2);
		makelink(s1,s2);
	}
	while(n--){
		scanf("%s",w);
		switch(w[0]){
			case '+':
				read(s1);read(s2);read(s3);
				change(s1,s2,s3,1);
				break;
			case '-':
				read(s1);read(s2);read(s3);read(s4);
				cut(s1,s2);makelink(s3,s4);
				break;
			case '*':
				read(s1);read(s2);read(s3);
				change(s1,s2,0,s3);
				break;
			case '/':
				read(s1);read(s2);
				work(s1,s2);
				break;
		}
	}
	
	return 0;
}
posted @ 2022-02-26 13:08  Feyn618  阅读(31)  评论(0编辑  收藏  举报