【link cut tree萌新】求助5分!昨天调了一晚上了……
查看原帖
【link cut tree萌新】求助5分!昨天调了一晚上了……
263082
A_zjzj楼主2022/3/11 17:52
#include<bits/stdc++.h>
using namespace std;
typedef int ui;
const ui N=1e5+10,mod=51061;
ui n,m;
struct node {
	ui fa,ch[2],rev,siz,val,sum,add,mul;
} a[N];
void pushup(ui x) {
	a[x].sum=(a[a[x].ch[0]].sum+a[x].val+a[a[x].ch[1]].sum)%mod;
	a[x].siz=a[a[x].ch[0]].siz+a[a[x].ch[1]].siz+1;
}
void pushrev(ui x) {
	a[x].rev^=1;
	swap(a[x].ch[0],a[x].ch[1]);
}
void pushadd(ui x,ui y) {
	(a[x].add+=y)%=mod;
	(a[x].sum+=y*a[x].siz)%=mod;
	(a[x].val+=y)%=mod;
}
void pushmul(ui x,ui y) {
	(a[x].add*=y)%=mod;
	(a[x].mul*=y)%=mod;
	(a[x].sum*=y)%=mod;
	(a[x].val*=y)%=mod;
}
void pushdown(ui x) {
	if(a[x].rev)pushrev(a[x].ch[0]),pushrev(a[x].ch[1]),a[x].rev=0;
	if(a[x].mul^1)pushmul(a[x].ch[0],a[x].mul),pushmul(a[x].ch[1],a[x].mul),a[x].mul=1;
	if(a[x].add)pushadd(a[x].ch[0],a[x].add),pushadd(a[x].ch[1],a[x].add),a[x].add=0;
}
bool isroot(ui x) {
	return a[a[x].fa].ch[0]!=x&&a[a[x].fa].ch[1]!=x;
}
bool which(ui x) {
	return a[a[x].fa].ch[1]==x;
}
void rotate(ui x) {
	ui y=a[x].fa,z=a[y].fa,k=which(x);
	if(!isroot(y))a[z].ch[which(y)]=x;
	a[x].fa=z;
	a[y].ch[k]=a[x].ch[k^1],a[a[x].ch[k^1]].fa=y;
	a[x].ch[k^1]=y,a[y].fa=x;
	pushup(y);
	pushup(x);
}
void update(ui x) {
	if(!isroot(x))update(a[x].fa);
	pushdown(x);
}
void splay(ui x) {
	update(x);
	for(ui y; y=a[x].fa,!isroot(x); rotate(x))if(!isroot(y))rotate(which(x)^which(y)?x:y);
}
void access(ui x) {
	ui z=x;
	for(ui y=0; x; x=a[y=x].fa)splay(x),a[x].ch[1]=y,pushup(x);
	splay(z);
}
void makeroot(ui x) {
	access(x);
	pushrev(x);
}
void split(ui x,ui y) {
	makeroot(x);
	access(y);
}
void link(ui x,ui y) {
	makeroot(x);
	a[x].fa=y;
}
void cut(ui x,ui y) {
	makeroot(x);
	a[x].ch[1]=a[y].fa=0,pushup(x);
}
void add(ui x,ui y,ui z) {
	split(x,y);
	pushadd(y,z);
}
void mul(ui x,ui y,ui z) {
	split(x,y);
	pushmul(y,z);
}
ui query(ui x,ui y) {
	split(x,y);
	return a[y].sum;
}
int main() {
	freopen(".in","r",stdin);
	scanf("%u%u",&n,&m);
	for(ui i=1; i<=n; i++)a[i].val=a[i].mul=a[i].sum=a[i].siz=1;
	for(ui i=1,u,v; i<n; i++)scanf("%u%u",&u,&v),link(u,v);
	char str[10];
	for(ui a,b,c,d; m--;) {
		scanf("%s%u%u",str,&a,&b);
		if(str[0]=='+')scanf("%u",&c),add(a,b,c);
		else if(str[0]=='-')scanf("%u%u",&c,&d),cut(a,b),link(c,d);
		else if(str[0]=='*')scanf("%u",&c),mul(a,b,c);
		else printf("%u\n",query(a,b));
	}
	return 0;
}
2022/3/11 17:52
加载中...