刚学树剖,30pts其他全wa了
查看原帖
刚学树剖,30pts其他全wa了
264548
Tangent233楼主2021/8/22 11:27
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node
{
	int l,r;
	long long val,result;
	int key,sz;
	long long plus;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define v(x) tree[x].val
	#define k(x) tree[x].key
	#define s(x) tree[x].sz
	#define p(x) tree[x].plus
	#define re(x) tree[x].result
}tree[maxn];
int cnt1,rt;
int x,y,z,mod;
inline int newnode(long long v)
{
	v(++cnt1)=v;
	k(cnt1)=rand();
	s(cnt1)=1;
	return cnt1;
}
inline void update(int now)
{
	s(now)=s(l(now))+s(r(now))+1;
	re(now)=re(l(now))+re(r(now))+v(now);
	re(now)%=mod;
}
inline void add(int now,long long v)
{
	v(now)+=v;
	p(now)+=v;
	re(now)+=v*s(now);
	v(now)%=mod;
	p(now)%=mod;
	re(now)%=mod;
}
inline void pushdown(int now)
{
	if(p(now)==0) return;
	add(l(now),p(now));
	add(r(now),p(now));
	p(now)=0;
}
void split(int now,int siz,int &x,int &y)
{
	if(!now) x=y=0;
	else
	{
		pushdown(now);
		if(s(l(now))<siz)
		{
			x=now;
			split(r(now),siz-s(l(now))-1,r(now),y);
		}
		else
		{
			y=now;
			split(l(now),siz,x,l(now));
		}
		update(now);
	}
}
int merge1(int x,int y)
{
	if(!x||!y) return x+y;
	if(k(x)<k(y))
	{
		pushdown(x);
		r(x)=merge1(r(x),y);
		update(x);
		return x;
	}
	else
	{
		pushdown(y);
		l(y)=merge1(x,l(y));
		update(y);
		return y;
	}
}
long long que(int l,int r)
{
	split(rt,l-1,x,y);
	split(y,r-l+1,y,z);
	long long ans=re(y);
	rt=merge1(merge1(x,y),z);
	return ans%mod;
}
void change(int l,int r,long long v)
{
	split(rt,l-1,x,y);
	split(y,r-l+1,y,z);
	add(y,v);
	rt=merge1(merge1(x,y),z);
}

vector <int> tree1[maxn]; 
int dep[maxn],fa[maxn],son[maxn],tot[maxn];
int b[maxn],a[maxn],idx[maxn],top[maxn];
int cnt;
int dfs1(int now,int f,int deep)
{
	dep[now]=deep;
	fa[now]=f;
	tot[now]=1;
	int maxson=-1;
	for(int i=0;i<tree1[now].size();i++)
	{
		int to=tree1[now][i];
		if(to==f) continue;
		tot[now]+=dfs1(to,now,deep+1);
		if(tot[to]>maxson)
		{
			son[now]=to;
			maxson=tot[to];
		}
	}
	return tot[now];
}
void dfs2(int now,int topf)
{
	idx[now]=++cnt;
	rt=merge1(rt,newnode(a[now]));
	top[now]=topf;
	if(!son[now]) return;
	dfs2(son[now],topf);
	for(int i=0;i<tree1[now].size();i++)
	{
		int to=tree1[now][i];
		if(!idx[to]) dfs2(to,to);
	}
}
int chainask(int x,int y)
{
	long long ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=que(idx[top[x]],idx[x]);
		ans%=mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=que(idx[x],idx[y]);
	return ans%mod;
}
void chainmodify(int x,int y,int k)
{
	k%=mod;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		change(idx[top[x]],idx[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	change(idx[x],idx[y],k);
}
int trask(int x)
{
	return que(idx[x],idx[x]+tot[x]-1);
}
void trmodify(int x,int k)
{
	k%=mod;
	change(idx[x],idx[x]+tot[x]-1,k);
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int main()
{
	int n,m,r;
	n=read();m=read();r=read();mod=read();
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<n;i++)
	{
		int fro,to;fro=read();to=read();
		tree1[fro].push_back(to);
		tree1[to].push_back(fro);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	for(int i=1;i<=m;i++)
	{
		int k,x,y,z;
		k=read();
		if(k==1)
		{
			//cin>>x>>y>>z;
			x=read();y=read();z=read();
			chainmodify(x,y,z);
		}
		else if(k==2)
		{
			x=read();y=read();
			cout<<chainask(x,y)<<endl;
		}
		else if(k==3)
		{
			x=read();z=read();
			trmodify(x,z);
		}
		else
		{
			x=read();
			cout<<trask(x)<<endl;
		}
	}
	return 0;
}
2021/8/22 11:27
加载中...