求调
查看原帖
求调
942071
_xzh_楼主2025/8/30 07:50
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
void read(int &a){
    a=0;int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        a=a*10+ch-'0';
		ch=getchar();
	}
	a=a*f;
}
int n,m,r,p,cnt,ans;
int a[100005];
struct node{
	int x,id;
};
vector<node> v[100005];
int aa[100005];
int mxsonnumber[100005];
int size[100005],mxson[100005];
int depth[100005],fa[100005];
int in[100005],top[100005];
int tree[400005],lazy[400005];
void dfs1(int father,int x,int dep){
	depth[x]=dep;
	fa[x]=father;
	size[x]=1;
	for(int i=0;i<v[x].size();i++){
		if(father==v[x][i].id)continue;
		dfs1(x,v[x][i].id,dep+1);
		size[x]+=size[v[x][i].id];
		if(size[v[x][i].id]>mxsonnumber[x]){
			mxsonnumber[x]=v[x][i].x;
			mxson[x]=v[x][i].id;
		}
	}
	return;
}
void dfs2(int x,int tp){
	in[x]=++cnt;
	aa[cnt]=a[x];
	top[x]=tp;
	if(!mxson[x])return;
	dfs2(mxson[x],tp);
	for(int i=0;i<v[x].size();i++){
		if(v[x][i].id==fa[x]||v[x][i].id==mxson[x]){
			continue;
		}
		dfs2(v[x][i].id,v[x][i].id);
	} 
} 
void pushdown(int x,int l){
	if(!lazy[x])return;
	lazy[x*2]+=lazy[x];
	lazy[x*2+1]+=lazy[x];
	tree[x*2]+=lazy[x]*(l-l/2);
	tree[x*2+1]+=lazy[x]*(l/2);
	tree[x*2]%=p,tree[x*2+1]%=p;
	lazy[x]=0;
}
void build(int x,int l,int r){
	if(l==r){
		tree[x]=aa[l]%p;
		return;
	}
	int mid=(l+r)/2;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	tree[x]=(tree[x*2]+tree[x*2+1])%p;
}
void query(int x,int l,int r,int ll,int rr){
	if(l>rr||rr<l)return;
	if(l>=ll&&r<=rr){
		ans+=tree[x];
		ans%=p;
		return;
	}
	pushdown(x,r-l+1);
	int mid=(l+r)/2;
	query(x*2,l,mid,ll,rr);
	query(x*2+1,mid+1,r,ll,rr);
}
void change(int x,int l,int r,int ll,int rr,int k){
	if(l>rr||rr<l)return;
	if(l>=ll&&r<=rr){
		tree[x]+=k*(r-l+1);
		lazy[x]+=k;
		return;
	}
	pushdown(x,r-l+1);
	int mid=(l+r)/2;
	change(x*2,l,mid,ll,rr,k);
	change(x*2+1,mid+1,r,ll,rr,k);
	tree[x]=tree[x*2]+tree[x*2+1];
	tree[x]%=p;
}

void change1(int x,int y,int k){
	k%=p;
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]]){
			swap(x,y);
		}
		change(1,1,n,in[top[x]],in[x],k);
		x=fa[top[x]];
	}
    if(depth[x]>depth[y])swap(x,y);
    change(1,1,n,in[x],in[y],k);
}
int query1(int x,int y){
	int s=0;
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]]){
			swap(x,y);
		}
		ans=0;
		query(1,1,n,in[top[x]],in[x]);
		s=(s+ans)%p;
		x=fa[top[x]];
	}
    if(depth[x]>depth[y])swap(x,y);
    ans=0;
    query(1,1,n,in[x],in[y]);
    return (ans+s)%p;
}
signed main(){
	read(n),read(m),read(r),read(p);
	for(int i=1;i<=n;i++){
		read(a[i]);
	}
	for(int i=1;i<n;i++){
		int ll,rr;
		read(ll),read(rr);
		v[ll].push_back((node){a[rr],rr});
		v[rr].push_back((node){a[ll],ll}); 
	}
	dfs1(0,r,1);
	dfs2(r,r);
	build(1,1,n);
	while(m--){
		int op;read(op);
		if(op==1){
			int l,r,x;
			read(l),read(r),read(x);
			change1(l,r,x);
		}
		else if(op==2){
			int l,r;
			read(l),read(r);
			printf("%d\n",query1(l,r));
		}
		else if(op==3){
			int x,y;
			read(x),read(y);
			change(1,1,n,in[x],in[x]+size[x]-1,y);
		}
		else{
			int x;read(x);
			ans=0;
			query(1,1,n,in[x],in[x]+size[x]-1);
			printf("%d\n",ans);
		}
	}
	return 0;
}

2025/8/30 07:50
加载中...