求救!
查看原帖
求救!
235431
lalalahahaha楼主2020/5/25 09:13
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0;char c=getchar();
	for(;!isdigit(c);c=getchar());
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	return x;
}

int n,m,r,p;
int tot=0,nex[200005],to[200005],head[100005];
int son[100005],fa[100005],dep[100005],id[100005],size[100005],top[100005],cnt=0;
int res=0;
int w[100005],wt[100005];

inline void add(int u,int v)
{
	nex[++tot]=head[u];
	head[u]=tot;
	to[tot]=v;
}

struct node
{
	int l,r;
	int ww,f;
}tree[400005];


inline void build(int l,int r,int k)
{
	tree[k].l=l;tree[k].r=r;
	if(l==r)
	{
		tree[k].ww=wt[l];tree[k].ww%=p; //
		return;
	}
	int mid=l+r>>1;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	tree[k].ww=(tree[k*2].ww+tree[k*2+1].ww)%p;
}

inline void down(int k)
{
	tree[k*2].f+=tree[k].f;
	tree[k*2+1].f+=tree[k].f;
	tree[k*2].ww+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
	tree[k*2+1].ww+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
	tree[k*2].ww%=p;
	tree[k*2+1].ww%=p;
	tree[k].f=0;
}

inline void ask(int k,int a,int b)
{
	//cout<<"ans"<<a<<"he"<<b<<endl;
	if(tree[k].l>=a&&tree[k].r<=b)
	{
		res+=tree[k].ww;res%=p;//printf("999");
		return;
	}
	down(k);
	int mid=(tree[k].l+tree[k].r)>>1;
	if(a<=mid) ask(k*2,a,b);
	if(b>mid) ask(k*2+1,a,b);//printf("888");
}

inline void change(int k,int a,int b,int ad)
{
	if(tree[k].l>=a&&tree[k].r<=b)
	{
		tree[k].f+=ad;
		tree[k].ww+=(tree[k].r-tree[k].l+1)*ad;
		return;
	}
	if(tree[k].f) down(k);
	int mid=(tree[k].l+tree[k].r)>>1;
	if(a<=mid) change(k*2,a,b,ad);
	if(b>mid) change(k*2+1,a,b,ad);
	tree[k].ww=(tree[k*2].ww+tree[k*2+1].ww)%p;
}
//**********************************以上线段树 
inline int ask2(int u,int v)
{
	int ans=0;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		res=0;
		ask(1,id[top[u]],id[u]);
		ans+=res;
		ans%=p;
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	res=0;
	ask(1,id[u],id[v]);
	ans+=res;
	return ans%p;
}

inline void change2(int u,int v,int z)
{
	z%=p;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		change(1,id[top[u]],id[u],z);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	change(1,id[u],id[v],z);
}

inline int askk(int k)
{
	int res=0;
	ask(1,id[k],id[k]+size[k]-1);
	return res;
}
inline void changek(int k,int ad)
{
	change(1,id[k],id[k]+size[k]-1,ad);
}

inline void dfs1(int u,int f)
{
	fa[u]=f;dep[u]=dep[f]+1;
	size[u]=1;int maxson=-1;
	for(int i=head[u];i;i=nex[i])
	{
		int v=to[i];
		if(v==f) continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>maxson)
		{
			maxson=size[v];
			son[u]=v;
		}
	}
}
inline void dfs2(int u,int tp)
{
	id[u]=++cnt;
	wt[++cnt]=w[u];
	top[u]=tp;
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i=head[u];i;i=nex[i])
	{
		int v=to[i];
		if(v==son[u]||v==fa[u]) continue;
		dfs2(v,v);
	}
}



int main()
{
	n=read();m=read();r=read();p=read();
	for(int i=1;i<=n;i++)
	{
		w[i]=read();
	}
	int a,b;
	for(int i=1;i<n;i++)
	{
		a=read();b=read();
		add(a,b);add(b,a);
	} 
	dfs1(r,0);
	dfs2(r,r);
	build(1,n,1);
	int opt,x,y,z;
	while(m--)
	{
		opt=read();
		if(opt==1)
		{
			x=read();y=read();z=read();
			change2(x,y,z);
		}
		if(opt==2)
		{
			x=read();y=read();
			printf("%d\n",ask2(x,y));
		}
		if(opt==3)
		{
			x=read();z=read();
			changek(x,z);
		}
		if(opt==4)
		{
			x=read();
			printf("%d\n",askk(x));
		}
	}
	
	
	return 0;
} 
2020/5/25 09:13
加载中...