Re
查看原帖
Re
800499
suzhikz楼主2024/12/16 21:11
#include<bits/stdc++.h>
#define ll long long
#define reg register
#define db double
#define il inline
using namespace std;
void read(int &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
void read(ll &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
const int N=1e5+5; 
int n,m,rt,mod;
int deep[N],fa[N],dfn[N],dfnr[N],idfn[N],son[N],top[N],sz[N],tim;
vector<int>g[N];
void dfs(int x){
	deep[x]=deep[fa[x]]+1;
	sz[x]=1;
	for(int i:g[x]){
		if(i==fa[x])continue;
		fa[i]=x;dfs(i);
		sz[x]+=sz[i];
		if(sz[i]>sz[son[x]])son[x]=i;
	}
}
void dfs2(int x,int tp){
//	cout<<x<<endl;
	top[x]=tp;
	dfn[x]=++tim;idfn[tim]=x;
	if(!son[x]){
		dfnr[x]=tim;return;
	}
	dfs2(son[x],tp);
	for(int i:g[x]){
		if(i==son[x])continue;
		if(i==fa[x])continue;
		dfs2(i,i);
	}
	dfnr[x]=tim;
}
ll a[N],tree[N<<2],tag[N<<2];
void push_down(int x,int l,int r){
	int mid=(l+r)/2;
	tree[x<<1]+=tag[x]*(mid-l+1)%mod;tree[x<<1|1]+=tag[x]*(r-mid)%mod;
	tree[x<<1]%=mod;tree[x<<1|1]%=mod;
	tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];
	tag[x]=0;
}
void push_up(int x){
	tree[x]=tree[x<<1]+tree[x<<1|1];
}
void build(int x,int l,int r){
	if(l==r){
		tree[x]=a[idfn[l]];return;
	}
	int mid=(l+r)/2;
	build(x<<1,l,mid);build(x<<1|1,mid+1,r);
	push_up(x);
}
void update(int x,int l,int r,int ql,int qr,int w){
//	cout<<x<<' '<<dfn[l]<<endl;
	if(ql<=l&&qr>=r){
		tree[x]+=(r-l+1)*w%mod;tree[x]%=mod;
		tag[x]+=w;return;
	}
	int mid=(l+r)/2;
	push_down(x,l,r);
	if(ql<=mid)update(x<<1,l,mid,ql,qr,w);
	if(qr>mid)update(x<<1|1,mid+1,r,ql,qr,w);
	push_up(x);
}
ll query(int x,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r)return tree[x];
	ll re=0;int mid=(l+r)/2;
	push_down(x,l,r);
	if(ql<=mid)re=query(x<<1,l,mid,ql,qr);
	if(qr>mid)re=(re+query(x<<1|1,mid+1,r,ql,qr))%mod;
	return re%mod;
}
void update2(int x,int y,ll z){
	while(top[x]!=top[y]){
//		cout<<x<<' '<<y<<endl;
		if(deep[x]<deep[y]){
			update(1,1,n,dfn[top[x]],dfn[x],z);
			x=fa[top[x]];
		}else{
			update(1,1,n,dfn[top[y]],dfn[y],z);
			y=fa[top[y]];
		}
	}
	update(1,1,n,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),z);
}
ll query2(int x,int y){
	ll re=0;
	while(top[x]!=top[y]){
//		cout<<x<<' '<<y<<endl;
		if(deep[x]>deep[y]){
			re+=query(1,1,n,dfn[top[x]],dfn[x]);
			x=fa[top[x]];
		}else{
			re+=query(1,1,n,dfn[top[y]],dfn[y]);
			y=fa[top[y]];
		}
		re%=mod;
	}
	re+=query(1,1,n,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]));
	return re%mod;
}
int main(){
	read(n);read(m);read(rt);read(mod);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int u,v,i=1;i<n;i++){
		read(u);read(v);
		g[u].push_back(v);g[v].push_back(u);
	}
	dfs(rt);dfs2(rt,rt);
	build(1,1,n);
	while(m--){
		int op,x,y,z;
		read(op);
		if(op==1){
			read(x);read(y);read(z);
			update2(x,y,z);
		}else if(op==2){
			read(x);read(z);
			printf("%lld\n",query2(x,z));
		}else if(op==3){
			read(x);read(z);
//			cout<<"up"<<dfn[x]<<' '<<dfnr[x]<<endl; 
			update(1,1,n,dfn[x],dfnr[x],z);
		}else{
			read(x);
			printf("%lld\n",query(1,1,n,dfn[x],dfnr[x]));
		}
	}
	return 0;
}

2024/12/16 21:11
加载中...