CR400BFAZ5254 @ 2024-07-16 15:36:31
#include<bits/stdc++.h>
#define MAXN 200010
#define lson (rt<<1)
#define rson ((rt<<1)|1)
using namespace std;
typedef long long ll;
ll n,m,r,p;
ll a[MAXN];
ll fa[MAXN],dep[MAXN],siz[MAXN],son[MAXN];
ll top[MAXN],dfn[MAXN],rnk[MAXN],id;
ll sum[MAXN<<2],add[MAXN<<2];
vector<int> e[MAXN];
void addedge(int x,int y){
e[x].push_back(y);
e[y].push_back(x);
}
void dfs1(int u,int p=0){
fa[u]=p;
dep[u]=dep[p]+1;
siz[u]=1;
son[u]=0;
for(auto v:e[u]){
if(v!=p){
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]){
son[u]=v;
}
}
}
}
void dfs2(int u,int t){
top[u]=t;
dfn[u]=++id;
rnk[id]=u;
if(!son[u]) return ;
dfs2(son[u],t);
for(auto v:e[u]){
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=a[rnk[l]]%p;
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
}
void push_color(int l,int r,int rt){
if(!add[rt]) return ;
int mid=(l+r)>>1;
add[rt<<1]+=add[rt];
sum[rt<<1]+=(ll)(mid-l+1)*add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1|1]+=(ll)(r-mid)*sum[rt];
add[rt<<1]%=p;
add[rt<<1|1]%=p;
sum[lson]%=p;
sum[rson]%=p;
add[rt]=0;
}
void update(int lp,int rp,int rt,int l,int r,int k){
if(l<=lp&&rp<=r){
add[rt]+=k;add[rt]%=p;
sum[rt]+=(ll)(r-l+1)*k;
sum[rt]%=p;
return ;
}
push_color(l,r,rt);
int mid=(l+r)>>1;
if(l<=mid) update(lp,mid,lson,l,r,k);
if(r>mid) update(mid+1,rp,rson,l,r,k);
sum[rt]=(sum[lson]+sum[rson])%p;
}
ll query(int lp,int rp,int rt,int l,int r){
ll s=0;
if(l<=lp&&rp<=r) return sum[rt]%p;
push_color(lp,rp,rt);
int mid=(l+r)>>1;
if(l<=mid) s=(s+query(lp,mid,lson,l,r))%p;
if(r>mid) s=(s+query(mid+1,r,rson,l,r))%p;
return s;
}
void update_son(ll x,ll v){
update(1,n,1,dfn[x],dfn[x]+siz[x]-1,v);
}
ll query_son(ll x){
return query(1,n,1,dfn[x],dfn[x]+siz[x]-1);
}
void update_chain(ll x,ll y,ll v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,n,1,dfn[top[x]],dfn[top[y]],v);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,n,1,dfn[x],dfn[y],v);
}
ll query_chain(ll x,ll y){
ll ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=query(1,n,1,dfn[top[x]],dfn[x]);
ans%=p;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(1,n,1,dfn[x],dfn[y]);
ans%=p;
return ans;
}
int main(){
scanf("%d%d%d%lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n-1;i++){
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
}
dfs1(r);
dfs2(r,r);
build(1,n,1);
while(m--){
int op,x,y,z;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&z);
update_chain(x,y,z%p);
}else if(op==2){
scanf("%d%d",&x,&y);
printf("%lld\n",query_chain(x,y)%p);
}else if(op==3){
scanf("%d%d",&x,&y);
update_son(x,y%p);
}else{
scanf("%d",&x);
printf("%lld\n",query_son(x)%p);
}
}
return 0;
}
by jianhe @ 2024-09-08 13:29:10
@CR400BFAZ5254
update_chain 函数里的
update(1,n,1,dfn[top[x]],dfn[top[y]],v);
是不是应该写成 update(1,n,1,dfn[top[x]],dfn[x],v);
by CR400BFAZ5254 @ 2024-09-08 13:37:03
@jianhe 还是挂
by jianhe @ 2024-09-18 20:58:19
@CR400BFAZ5254 push_color
中
sum[rt<<1|1]+=(ll)(r-mid)*sum[rt];
写错了
by CR400BFAZ5254 @ 2024-09-18 21:02:27
依然改变不了RE的事实