调了2.5小时 求大佬 看看 RE30%
查看原帖
调了2.5小时 求大佬 看看 RE30%
267778
sfksf楼主2021/11/10 21:09
#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ri register int

int n,m,R;
long long P;
long long  val[M];
vector <int> p[M];

void read()     // ok
{
	scanf("%d%d%d%lld",&n,&m,&R,&P);
	for(ri i=1;i<=n;i++)
	{
		scanf("%lld",&val[i]);
	}
	for(ri i=1;i<n;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		p[a].push_back(b);
		p[b].push_back(a);
	}
}

int dep[M],sz[M],fa[M],son[M];
int  vis[M];

void dfs1(int r,int f)
{
   	 fa[r]=f;
   	 dep[r]=dep[f]+1;
   	 vis[r]=1;
   	 int maxz=0;
   	 sz[r]=1;
   	 for(ri i=0;i<p[r].size();i++)
   	 {
   	 	int b=p[r][i];
   	 	if(vis[b]) continue ;
   	 	dfs1(b,r);
   	 	sz[r]+=sz[b];
   	 	if(maxz<sz[b])
   	 	{
   	 		son[r]=b;
   	 		maxz=sz[b];
		}
	 }
   	 
}

int id[M],hao[M];
int cur,top[M],addr[M];
void dfs2(int r,int f)
{
	vis[r]=1;
	id[r]=++cur;
	addr[cur]=r;
	top[r]=f;
	
	if(son[r]) dfs2(son[r],f);
	
	for(ri i=0;i<p[r].size();i++)
	{
		int b=p[r][i];
		if(vis[b]) continue;
		dfs2(b,b);
	}
	hao[r]=cur;
	
}

struct xdhsu{
	int l,r;
	long long val;
}tr[M];
void build(int l,int r,int i)
{   
     tr[i].l=l;tr[i].r=r;
    if(l==r)
    {
    	tr[i].val=val[addr[l]]; // 
    	return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,i<<1);
	build(mid+1,r,i<<1|1);
	tr[i].val+=tr[i<<1].val;
	tr[i].val+=tr[i<<1|1].val;
	tr[i].val%=P;
}

long long  lz[M];

void down(int i)
{
	if(!lz[i]) return ;
	lz[i<<1]+=lz[i];lz[i<<1]%=P;
	lz[i<<1|1]+=lz[i];lz[i<<1|1]%=P;
	tr[i<<1].val+=(tr[i<<1].r-tr[i<<1].l+1)*lz[i]%P;tr[i<<1].val%=P;
	
	tr[i<<1|1].val+=(tr[i<<1|1].r-tr[i<<1|1].l+1)*lz[i]%P;tr[i<<1|1].val%=P;
	lz[i]=0;
} 
void xiu(int l,int r,int i,int k)
{
	if(l>tr[i].r||r<tr[i].l) return ;
	if(l<=tr[i].l&&r>=tr[i].r)
	{
		tr[i].val+=(tr[i].r-tr[i].l+1)*k%P;
		tr[i].val%=P;
		lz[i]+=k%P; //// ky ba
		lz[i]%=P;
		return ;	
	}
	down(i);
	xiu(l,r,i<<1,k);
	xiu(l,r,i<<1|1,k);
	tr[i].val=(tr[i<<1].val+tr[i<<1|1].val)%P;
}

long long  qu(int l,int r,int i)
{
	if(l>tr[i].r||r<tr[i].l) return 0;
	if(l<=tr[i].l&&r>=tr[i].r)
	{
		
		return tr[i].val%P;	
	}
	down(i);
	return (qu(l,r,i<<1)+qu(l,r,i<<1|1))%P;
}

void xlca(int a,int b,int k)
{
	while(top[a]!=top[b])
	{
		if(dep[top[a]]>dep[top[b]])
		swap(a,b);
		xiu(id[top[b]],id[b],1,k);
		b=fa[top[b]];
	}
	if(dep[a]>dep[b]) swap(a,b);
	xiu(id[a],id[b],1,k);
}
long long clca(int a,int b)
{
	   long long ans=0;
		while(top[a]!=top[b])
	    {
		 if(dep[top[a]]>dep[top[b]])
		 swap(a,b);
		 ans=(ans+qu(id[top[b]],id[b],1))%P;
		  b=fa[top[b]];
	    }
	if(dep[a]>dep[b]) swap(a,b);
       ans=(ans+qu(id[a],id[b],1))%P;
       return ans;
}

void solve()
{
	dfs1(R,0);
	memset(vis,0,sizeof(vis));
	dfs2(R,R);

	build(1,cur,1);

	for(ri i=1;i<=m;i++)
	{
		int a;
		scanf("%d",&a);
		if(a==1)
		{
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			xlca(x,y,z);
		}
		if(a==2)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			
			long long anss;
			anss=clca(x,y)%P;
			printf("%lld\n",anss);
		}
		if(a==3)
		{
			int x,z;
			scanf("%d%d",&x,&z);
			xiu(id[x],hao[x],1,z);
		}
		if(a==4)
		{
			int x;
			scanf("%d",&x);
			long long anss=qu(id[x],hao[x],1)%P;
			printf("%lld\n",anss);
			
		}
	}
}

int main(){
	
	read();
	solve();

	return 0;
	
}   
2021/11/10 21:09
加载中...