灌佬多,求条P3384 19pts
查看原帖
灌佬多,求条P3384 19pts
380639
dthythxth_Huge_Brain楼主2024/7/22 10:47
#include<bits/stdc++.h>
#define int long long
struct st{
    int to,next;
}v[200003];
int a[100002],real[500002],lzy[500005],head[100002],tr[100003],id[100003],fa[100002],son[100002],deep[100002],sze[100003],tp[100003],n,m,rt,mod,len,tot,x,y,z,opt;
void add(int x,int y){
    v[++len].to=y,v[len].next=head[x],head[x]=len;
}
void pushup(int x){
    tr[x]=tr[x*2]+tr[x*2+1];
}
void pushdown(int x,int l,int r){
    if(lzy[x])tr[x*2]+=lzy[x]*l,tr[x*2+1]+=lzy[x]*r,lzy[x*2]+=lzy[x],lzy[x*2+1]+=lzy[x],lzy[x]=0;
} 
void build(int x,int l,int r){
    if(l==r){
        tr[x]=a[real[l]];
        return;
    }
    int mid=l+r>>1;
    build(x*2,l,mid),build(x*2+1,mid+1,r),pushup(x);
}
void update(int x,int l,int r,int L,int R,int val){
    if(l>=L&&r<=R){
        tr[x]+=val*(r-l+1),lzy[x]+=val;
        return;
    }
    int mid=l+r>>1;
    pushdown(x,mid-l+1,r-mid);
    if(mid>=L)update(x*2,l,mid,L,R,val);
	if(mid<R)update(x*2+1,mid+1,r,L,R,val);
}
int query(int x,int l,int r,int L,int R){
//	std::cout<<l<<' '<<r<<' '<<L<<' '<<R<<'\n'; 
	if(l>=L&&r<=R)return tr[x]%mod;
//	puts("222");
	int ans=0,mid=l+r>>1;
	pushdown(x,mid-l+1,r-mid);
//	puts("333");
	if(mid>=L)ans+=query(x*2,l,mid,L,R),ans%=mod;
	if(mid+1<=R)ans+=query(x*2+1,mid+1,r,L,R),ans%=mod;
	pushup(x);
	return ans;
}
void dfs(int u,int fath){
    fa[u]=fath,sze[u]=1;
    for(int i=head[u],w;i;i=v[i].next){
        w=v[i].to;
        if(fath^w){
            deep[w]=deep[u]+1,dfs(w,u);
            if(sze[son[u]]<sze[w]||!son[u])son[u]=w;
            sze[u]+=sze[w];
        }
    }
}
void DFS(int u,int val){
    tp[u]=val,id[u]=++tot,real[tot]=u;
    if(!son[u])return;
    else DFS(son[u],val);
    for(int i=head[u],w;i;i=v[i].next){
        w=v[i].to;
        if(fa[u]^w&&w^son[u])DFS(w,w);
    }
}
void sol1(){
    scanf("%lld%lld%lld",&x,&y,&z);
    int A=tp[x],B=tp[y];
    while(A^B){
        if(deep[A]<deep[B])std::swap(A,B),std::swap(x,y);
        update(1,1,n,id[A],id[x],z),x=fa[A],A=tp[x];
    }
    if(deep[x]>deep[y])std::swap(x,y);
    update(1,1,n,id[x],id[y],z);
}
void sol2(){
    scanf("%lld%lld",&x,&y);
    int A=tp[x],B=tp[y],ans=0;
    while(A^B){
        if(deep[A]<deep[B])std::swap(A,B),std::swap(x,y);
        ans+=query(1,1,n,id[A],id[x]),ans%=mod,x=fa[A],A=tp[x];
    }
    if(deep[x]>deep[y])std::swap(x,y);
    ans+=query(1,1,n,id[x],id[y]),printf("%lld\n",ans%mod); 
}
void sol3(){
    scanf("%lld%lld",&x,&y),update(1,1,n,id[x],id[x]+sze[x]-1,y);
}
void sol4(){
    scanf("%lld",&x);
//    std::cout<<id[x]<<' '<<sze[x];
	printf("%lld\n",query(1,1,n,id[x],id[x]+sze[x]-1)%mod);
}
signed main(){
    scanf("%lld%lld%lld%lld",&n,&m,&rt,&mod),deep[rt]=1;
    for(int i=1;i<=n;i++)scanf("%lld",a+i);
    for(int i=1;i<n;i++)scanf("%lld%lld",&x,&y),add(x,y),add(y,x);
    dfs(rt,0),DFS(rt,rt),build(1,1,n);
    for(;m--;){
        scanf("%lld",&opt);
        if(opt==1)sol1();
        else if(opt==2)sol2();
        else if(opt==3)sol3();
        else sol4();
    }
    return 0;
}

2024/7/22 10:47
加载中...