73pts求调
查看原帖
73pts求调
1773073
gxyzstarsky楼主2025/6/18 20:27
#include<iostream>
#include<vector> 
#include<bitset>
#define int long long
using namespace std;
int n,m,srt,p,dt[100000],s,t,st[100000],sn[100000],stp[100000],sq[100000],ps[100000],sl[400000],sr[400000],v[400000],lzy[400000],k,sg,x,y,z,dep[100000],ans,fa[100000];
vector<int> tr[100000];
bool vis[100000];
void dfs1(int rt){
	vis[rt]=true;
	st[rt]=1;
	sn[rt]=-1;
	for(int i=0;i<tr[rt].size();i++){
		if(!vis[tr[rt][i]]){
			dep[tr[rt][i]]=dep[rt]+1;
			fa[tr[rt][i]]=rt;
			dfs1(tr[rt][i]);
			st[rt]+=st[tr[rt][i]];
			if(st[sn[rt]]<st[tr[rt][i]]){
				sn[rt]=tr[rt][i];
			}
		}
	}
	return;
}
void dfs2(int tp,int rt){
	vis[rt]=false;
	stp[rt]=tp;
	sq[k]=rt;
	ps[rt]=k;
	k++;
	if(sn[rt]!=-1){
		dfs2(tp,sn[rt]);
	}
	for(int i=0;i<tr[rt].size();i++){
		if(vis[tr[rt][i]]){
			dfs2(tr[rt][i],tr[rt][i]);
		}
	}
	return;
}
void psd(int ix){
	lzy[ix<<1]+=lzy[ix]%p;
	lzy[ix<<1]%=p;
	v[ix<<1]+=lzy[ix]*(sr[ix<<1]-sl[ix<<1]+1)%p;
	v[ix<<1]%=p;
	lzy[(ix<<1)^1]+=lzy[ix]%p;
	lzy[(ix<<1)^1]%=p;
	v[(ix<<1)^1]+=lzy[ix]*(sr[(ix<<1)^1]-sl[(ix<<1)^1]+1)%p;
	v[ix]%=p;
	lzy[ix]=0;
	return;
}
void crt(int ix,int l,int r){
	sl[ix]=l;
	sr[ix]=r;
	if(l!=r){
		crt(ix<<1,l,(l+r)>>1);
		crt((ix<<1)^1,((l+r)>>1)+1,r);
		v[ix]=(v[ix<<1]+v[(ix<<1)^1])%p;
	}
	else{
		v[ix]=dt[sq[l]]%p;
	}
	return;
}
void upd(int ix,int l,int r,int c){
	psd(ix);
	if(sl[ix]!=l||sr[ix]!=r){
	    if(r<=(sl[ix]+sr[ix])>>1){
		    upd(ix<<1,l,r,c);
	    }
		else if(l>(sl[ix]+sr[ix])>>1){
			upd((ix<<1)^1,l,r,c);
		}
		else{
			upd(ix<<1,l,(sl[ix]+sr[ix])>>1,c);
			upd((ix<<1)^1,((sl[ix]+sr[ix])>>1)+1,r,c);
		}
		v[ix]=(v[ix<<1]+v[(ix<<1)^1])%p;
	}
	else{
		lzy[ix]+=c;
		lzy[ix]%=p;
		v[ix]+=c*(sr[ix]-sl[ix]+1)%p;
		v[ix]%=p;
	}
	return;
}
int qry(int ix,int l,int r){
	psd(ix);
	if(sl[ix]!=l||sr[ix]!=r){
	    if(r<=(sl[ix]+sr[ix])>>1){
		    return qry(ix<<1,l,r)%p;
	    }
		else if(l>(sl[ix]+sr[ix])>>1){
			return qry((ix<<1)^1,l,r)%p;
		}
		else{
			return qry(ix<<1,l,(sl[ix]+sr[ix])>>1)%p+qry((ix<<1)^1,((sl[ix]+sr[ix])>>1)+1,r)%p;
		}
	}
	else{
		return v[ix]%p;
	}
}
signed main(){
	//freopen("P3384_8.in","r",stdin);
	scanf("%lld%lld%lld%lld",&n,&m,&srt,&p);
	for(int i=0;i<n;i++){
	   scanf("%lld",&dt[i]);
	   dt[i]%=p;	
	}
	for(int i=0;i<n-1;i++){
		scanf("%lld%lld",&s,&t);
		tr[s-1].push_back(t-1);
		tr[t-1].push_back(s-1);
	}
	dfs1(srt-1);
	dfs2(srt-1,srt-1);
	crt(1,0,n-1);
	for(int i=0;i<m;i++){
		scanf("%lld",&sg);
		switch(sg){
			case 1:
			    scanf("%lld%lld%lld",&x,&y,&z);
			    z%=p;
			    x--;
			    y--;
			    while(stp[x]!=stp[y]){
			    	if(dep[stp[x]]<dep[stp[y]]){
			    		swap(x,y);
					}
					upd(1,ps[stp[x]],ps[x],z);
			    	x=fa[stp[x]];
				}
				if(dep[x]<dep[y]){
					upd(1,ps[x],ps[y],z);
				}
				else{
					upd(1,ps[y],ps[x],z);
				}
				break;
			case 2:
			    scanf("%lld%lld",&x,&y);
			    x--;
			    y--;
			    ans=0;
			    while(stp[x]!=stp[y]){
			    	if(dep[stp[x]]<dep[stp[y]]){
			    		swap(x,y);
					}
					ans+=qry(1,ps[stp[x]],ps[x])%p;
			    	x=fa[stp[x]];
				}
				if(dep[x]<dep[y]){
					ans+=qry(1,ps[x],ps[y])%p;
				}
				else{
					ans+=qry(1,ps[y],ps[x])%p;
				}
				printf("%lld\n",ans%p);
				break;
			case 3:
			    scanf("%lld%lld",&x,&z);
			    z%=p;
			    upd(1,ps[x-1],ps[x-1]+st[x-1]-1,z);
			    break;
			case 4:
				scanf("%lld",&x);
				printf("%lld\n",qry(1,ps[x-1],ps[x-1]+st[x-1]-1)%p);
				break;
			default:
				break;
		}
	}
	return 0;
}
2025/6/18 20:27
加载中...