社区讨论

萌新刚学LCT,求调代码

P1501[国家集训队] Tree II参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lz2hbzxk
此快照首次捕获于
2024/07/26 17:07
2 年前
此快照最后确认于
2024/07/26 18:29
2 年前
查看原帖
rt,只有 55pts,小数据完全手造不出 hack,生成器不会写/kel
CPP
#include <bits/stdc++.h>
#define ll long long
#define int long long
#define wdnmd const int mod=::mod;
#define lb(i) ((i)&(-(i)))
#define wr(x,ch) write(x),putchar(ch)
using namespace std;
#define gh() getchar()
inline long long read(){
	char ch=gh();
	long long x=0;
	char t=0;
	while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
	return t?-x:x;
}
void write(ll x) {
    if(x<0) putchar('-'),x=-x;
    if(x>=10) write(x/10);
    putchar(x%10^48);
    return ;
}
const int N=1e5+5,mod=51061;
struct Others {
	struct node {
		int val,ch[2],tag1,tag2,rev,sum,siz,fa;
	}tr[N];
	int sta[N],top;
	void pushup(int p) {
		tr[p].sum=(tr[tr[p].ch[0]].sum+tr[tr[p].ch[1]].sum+tr[p].val)%mod;
		tr[p].siz=tr[tr[p].ch[0]].siz+tr[tr[p].ch[1]].siz+1;
		return ;
	}
	void update(int p,int t1,int t2,int c) {
		if(!p) return ;
		tr[p].val=(tr[p].val*t1+t2)%mod;
		tr[p].sum=(tr[p].sum*t1+t2*tr[p].siz)%mod;
		tr[p].tag1=tr[p].tag1*t1%mod;
		tr[p].tag2=(tr[p].tag2*t1+t2)%mod;
		if(c) tr[p].rev^=1,swap(tr[p].ch[0],tr[p].ch[1]); 
		return ;
	}
	void pushdown(int p) {
		if(tr[p].tag1!=1||tr[p].tag2||tr[p].rev) {
			update(tr[p].ch[0],tr[p].tag1,tr[p].tag2,tr[p].rev);
			update(tr[p].ch[1],tr[p].tag1,tr[p].tag2,tr[p].rev);
			tr[p].tag1=1,tr[p].tag2=tr[p].rev=0;
		}
		return ;
	}
	bool isr(int p) {
		return tr[tr[p].fa].ch[0]!=p&&tr[tr[p].fa].ch[1]!=p;
	}
	void rot(int x) {
		int y=tr[x].fa,z=tr[y].fa;
		pushdown(y),pushdown(x);
		int op=(x==tr[y].ch[1]);
		if(!isr(y)) tr[z].ch[y==tr[z].ch[1]]=x;
		tr[x].fa=z,tr[y].fa=x;
		tr[tr[x].ch[op^1]].fa=y,tr[y].ch[op]=tr[x].ch[op^1];
		tr[x].ch[op^1]=y;
		pushup(y),pushup(x);
		return ;
	}
	void splay(int p) {
		sta[top=1]=p;
		for(int i=p;!isr(i);i=tr[i].fa) sta[++top]=tr[i].fa;
		while(top) pushdown(sta[top--]);
		while(!isr(p)) {
			int y=tr[p].fa,z=tr[y].fa;
			if(!isr(y)) {
				if((p==tr[y].ch[0])^(y==tr[z].ch[0])) rot(p);
				else rot(y);
			}rot(p);
		}
		return ;
	}
	void access(int p) {
		int tmp=0;
		while(p) {
			splay(p);
			tr[p].ch[1]=tmp,pushup(p);
			tmp=p,p=tr[p].fa;
		}
		return ;
	}
	void makeroot(int p) {
		access(p);
		splay(p);
		update(p,1,0,1);
		return ;
	}
	void split(int u,int v) {
		makeroot(u);
		access(v);
		splay(v);
		return ;
	}
	void cut(int u,int v) {
		split(u,v);
		if(tr[v].ch[0]==u&&tr[u].ch[1]==0) tr[u].fa=0,tr[v].ch[0]=0;
		pushup(v);
		return ;
	}
	void link(int u,int v) {
		makeroot(u),tr[u].fa=v;
		pushup(v);
		return ;
	}
}T;
void solve() {
	int n=read(),q=read();
	for(int i=1;i<=n;i++) T.tr[i]=(Others::node){1,0,0,1,0,0,1,0};
	for(int i=1;i<n;i++) {
		int u=read(),v=read();
		T.link(u,v);
	}
	for(int i=1;i<=q;i++) {
		char op[15];
		scanf("%s",op);
		int u=read(),v=read();
		if(op[0]=='+') {
			int c=read();
			T.split(u,v);
			T.splay(u);
			T.update(u,1,c,0);
		}else if(op[0]=='-') {
			T.cut(u,v);
			u=read(),v=read();
			T.link(u,v);
		}else if(op[0]=='*') {
			int c=read();
			T.split(u,v);
			T.splay(u);
			T.update(u,c,0,0);
		}else {
			T.split(u,v),T.splay(u);
			wr(T.tr[u].sum,'\n');
		}
	}
	return ;
}
signed main() {
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
	int T=1;
	while(T--) solve();
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...