Kniqht @ 2023-12-30 16:06:35
rt,不知道哪里写挂了,三个点AC 5ms别的都T了,很抽象,悬赏本号的关注/kk
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10,M=4e5+10;
int n,m,R;ll mod;
int h[N],e[M*2],ne[M*2],idx;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dep[N],fa[N],sz[N],top[N],son[N];
int id[N],cnt;
ll w[N],nw[N];
struct Nd{
int l,r;
ll add,v;
}tr[N*4];
void dfs1(int u,int father,int depth){
dep[u]=depth,fa[u]=father,sz[u]=1;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==father) continue;
dfs1(j,u,depth+1);
sz[u]+=sz[j];
if(sz[j]>sz[son[u]]) son[u]=j;
}
}
void dfs2(int u,int t){
id[u]=++cnt,nw[cnt]=w[u],top[u]=t;
if(!son[u]) return;
dfs2(son[u],t);
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==fa[u]||j==son[u]) continue;
dfs2(j,j);
}
}
void pushup(int u){
tr[u].v=(tr[u<<1].v+tr[u<<1|1].v)%mod;
}
void pushdown(int u){
Nd &rt=tr[u],&lc=tr[u<<1],&rc=tr[u<<1|1];
if(!rt.add) return;
lc.add=(lc.add+rt.add)%mod;rc.add=(rc.add+rt.add)%mod;
lc.v=(lc.v+(ll)(lc.r-lc.l+1)*rt.add%mod)%mod;
rc.v=(rc.v+(ll)(rc.r-rc.l+1)*rt.add%mod)%mod;
rt.add=0;
}
void build(int u,int l,int r){
tr[u]={l,r,0,nw[r]};
if(l==r) return;
int mid=l+r>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,ll k){
if(tr[u].l>r||tr[u].r<l) return;
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].add=(tr[u].add+k)%mod;
tr[u].v=(tr[u].v+(ll)(tr[u].r-tr[u].l+1)*k%mod)%mod;
return;
}
pushdown(u);
update(u<<1,l,r,k);update(u<<1|1,l,r,k);
pushup(u);
}
ll query(int u,int l,int r){
if(tr[u].l>r||tr[u].r<l) return 0;
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].v%mod;
pushdown(u);
return (query(u<<1,l,r)+query(u<<1|1,l,r))%mod;
pushup(u);
}
void update_path(int u,int v,int k){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(1,id[top[u]],id[u],k);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
update(1,id[v],id[u],k);
}
ll get_path(int u,int v){
ll res=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=(res+query(1,id[top[u]],id[u]))%mod;
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res=(res+query(1,id[v],id[u]))%mod;
return res;
}
ll get_tree(int u){
return query(1,id[u],id[u]+sz[u]-1);
}
void update_tree(int u,ll k){
update(1,id[u],id[u]+sz[u]-1,k);
}
signed main(){
scanf("%d%d%d%d",&n,&m,&R,&mod);
for(int i=1;i<=n;i++) scanf("%lld",&w[i]),w[i]%=mod;
memset(h,-1,sizeof(h));int a,b;
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs1(R,-1,1);dfs2(R,1);build(1,1,n);
while(m--){
int t,u,v,k;
scanf("%d%d",&t,&u);
if(t==1){
scanf("%d%d",&v,&k);k%=mod;
update_path(u,v,k);
}
else if(t==3){
scanf("%d",&k);k%=mod;
update_tree(u,k);
}
else if(t==2){
scanf("%d",&v);
printf("%lld\n",get_path(u,v)%mod);
}
else printf("%lld\n",get_tree(u)%mod);
}
return 0;
}
by Loser_Syx @ 2023-12-30 16:13:10
@Kniqht 您好,dfs2
函数中以根为起点的重链的 top
应该是根不是 1
捏。
by Kniqht @ 2023-12-30 17:13:33
@Loser_Syx 草,感谢您
by Kniqht @ 2023-12-30 17:13:46
复制粘贴导致的