[BZOJ2631]Tree

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ2631]Tree相关的知识,希望对你有一定的参考价值。

大概是模板题中的一个吧,标记维护同BZOJ1798

一开始把读入用的字符串声明成s楞是没发现,编译可以过而且没有warning......

很走心地用long long,但在BZOJ上用unsigned才过得了

#include<stdio.h>
#define ll unsigned
int fa[100010],ch[100010][2],r[100010],siz[100010];
ll v[100010],s[100010],ad[100010],mu[100010];
#define ls ch[x][0]
#define rs ch[x][1]
ll mo(ll x){return x%51061;}
void pushup(int x){
	s[x]=mo(v[x]+s[ls]+s[rs]);
	siz[x]=siz[ls]+siz[rs]+1;
}
void madd(int x,ll a,ll b){
	v[x]=mo(v[x]*a+b);
	s[x]=mo(s[x]*a+siz[x]*b);
	ad[x]=mo(ad[x]*a+b);
	mu[x]=mo(mu[x]*a);
}
void swap(int&a,int&b){a^=b^=a^=b;}
void rev(int x){
	r[x]^=1;
	swap(ls,rs);
}
void pushdown(int x){
	if(r[x]){
		if(ls)rev(ls);
		if(rs)rev(rs);
		r[x]=0;
	}
	if(mu[x]^1|ad[x]){
		if(ls)madd(ls,mu[x],ad[x]);
		if(rs)madd(rs,mu[x],ad[x]);
		mu[x]=1;
		ad[x]=0;
	}
}
bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void gao(int x){
	if(!isrt(x))gao(fa[x]);
	pushdown(x);
}
void rot(int x){
	int y,z,f,B;
	y=fa[x];
	z=fa[y];
	f=ch[y][0]==x;
	B=ch[x][f];
	fa[x]=z;
	fa[y]=x;
	if(B)fa[B]=y;
	ch[x][f]=y;
	ch[y][f^1]=B;
	if(ch[z][0]==y)ch[z][0]=x;
	if(ch[z][1]==y)ch[z][1]=x;
	pushup(y);
	pushup(x);
}
void splay(int x){
	gao(x);
	int y,z;
	while(!isrt(x)){
		y=fa[x];
		z=fa[y];
		if(!isrt(y))rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x);
		rot(x);
	}
}
void access(int x){
	int y=0;
	while(x){
		splay(x);
		rs=y;
		pushup(x);
		y=x;
		x=fa[x];
	}
}
void makert(int x){
	access(x);
	splay(x);
	rev(x);
}
void link(int x,int y){
	makert(x);
	fa[x]=y;
}
void cut(int x,int y){
	makert(x);
	access(y);
	splay(y);
	ch[y][0]=0;
	fa[x]=0;
	pushup(y);
}
void modify(int x,int y,int a,int b){
	makert(x);
	access(y);
	splay(y);
	madd(y,a,b);
}
int query(int x,int y){
	makert(x);
	access(y);
	splay(y);
	return s[y];
}
int main(){
	int n,q,i,x,y,c;
	char ss[4];
	scanf("%d%d",&n,&q);
	for(i=1;i<=n;i++)mu[i]=v[i]=s[i]=siz[i]=1;
	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		link(x,y);
	}
	while(q--){
		scanf("%s",ss);
		if(ss[0]==‘+‘){
			scanf("%d%d%d",&x,&y,&c);
			modify(x,y,1,c);
		}
		if(ss[0]==‘-‘){
			scanf("%d%d%d%d",&x,&y,&c,&i);
			cut(x,y);
			link(c,i);
		}
		if(ss[0]==‘*‘){
			scanf("%d%d%d",&x,&y,&c);
			modify(x,y,c,0);
		}
		if(ss[0]==‘/‘){
			scanf("%d%d",&x,&y);
			printf("%d\n",query(x,y));
		}
	}
}

以上是关于[BZOJ2631]Tree的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2631tree link-cut-tree

BZOJ2631: tree

BZOJ 2631: tree

BZOJ 2631 tree 动态树(Link-Cut-Tree)

BZOJ2631: tree LCT

BZOJ2631 tree(伍一鸣) LCT 秘制标记