求助
查看原帖
求助
563069
UQAQU楼主2024/8/1 22:29
#include<bits/stdc++.h>
#define ll long long int
const int N=5e6+7;
using namespace std;
struct tree{
    int to,next,w;
}edge[2*N];
int n,m,r,mod;
int head[N],cnt,deep[N],sum[N],ch[N];
int top[N],fa[N],son[N],number,size[N],val[N],lazy[N],id[N];
void add_edge(int u,int v){
    cnt++;
    edge[cnt].to=v,edge[cnt].next=head[u],head[u]=cnt;
}
void dfs1(int u,int v){
    deep[u]=deep[v]+1;
    fa[u]=v;
    size[u]=1;
    for (int i=head[u];i!=0;i=edge[i].next){
        int j=edge[i].to;
        if (j==v){
            continue;
        }
        dfs1(j,u);
        size[u]+=size[j];
        if (size[j]>size[son[u]]){
            son[u]=j;
        }
    }
}
void dfs2(int u,int v){
    number++;
    id[u]=number,val[number]=u,top[u]=v;
    if (!son[u]){
        return ;
    }
    dfs2(son[u],v);
    for (int i=head[u];i!=0;i=edge[i].next){
        int j=edge[i].to;
        if (j!=fa[u] && j!=son[u]){
            dfs2(j,j);
        }
    }
    return ;
}
void build(int u,int l,int r){
    if (l==r){
        sum[l]=ch[val[u]];
        return ;
    }
    int mid=(l+r)>>1;
    build(2*u,l,mid);
    build(2*u+1,mid+1,r);
    sum[u]+=sum[2*u]+sum[2*u+1];
    sum[u]%=mod;
    return ;
}
void push(int u,int l,int r){
    int mid=(l+r)>>1;
    lazy[2*u]+=lazy[u];lazy[2*u]%=mod;
    lazy[2*u+1]+=lazy[u];lazy[2*u+1]%=mod;
    sum[2*u]+=lazy[u]*(mid-l+1);sum[2*u]%=mod;
    sum[2*u+1]+=lazy[u]*(r-mid);sum[2*u]%=mod;
    lazy[u]=0;
    return ;
}
void update(int u,int s,int t,int l,int r,int k){
    if (l<=s && r>=t){
        sum[u]+=k*(t-s+1);sum[u]%=mod;
        lazy[u]+=k;lazy[u]%=mod;
        return ;
    }
    if(s>r||t<l)return ;
    int mid=(s+t)>>1;
    if (lazy[u]!=0){
        push(u,s,t);
    }
    if (l>=mid){
        update(2*u,s,mid,l,r,k);
    }
    if (r>mid){
        update(2*u+1,mid+1,t,l,r,k);
    }
    sum[u]=(sum[2*u]+sum[2*u+1])%mod;
    return ;
}
ll query(int u,int s,int t,int l,int r){
    if (l<=s && r>=t){
        return sum[u]%=mod;
    }
    if(s>r|| t<l) return 0;
    int mid=(s+t)>>1;
    ll ans=0;
    if (mid>=l){
        ans+=query(2*u,s,mid,l,r);
        ans%=mod;
    }
    if (r>mid){
        ans+=query(2*u+1,mid+1,t,l,r);
        ans%=mod;
    }
    return ans%=mod;
}
ll query_sum(int u,int v){
    ll ans=0;
    while (top[u]!=top[v]){
        if (deep[top[u]]<deep[top[v]]){
            swap(u,v);
        }
        ans+=query(1,1,number,id[top[u]],id[u]);
        u=fa[top[u]];
    }
    if (id[u]<id[v]){
        swap(u,v);
    }
    ans+=query(1,1,number,id[v],id[u]);
    return ans;
}
void update_path(int u,int v,int k){
    while (top[u]!=top[v]){
        if (deep[u]<deep[v]){
            swap(u,v);
        }
        update(1,1,number,id[top[u]],id[u],k);
        u=fa[top[u]];
    }
    if (id[u]<id[v]){
        swap(u,v);
    }
    update(1,1,number,id[v],id[u],k);
}
int main()
{
    int n,m,r,mod;
    cin>>n>>m>>r>>mod;
    for (int i=1;i<=n;i++){
        cin>>ch[i];
    }
    for (int i=1;i<=n-1;i++){
        int x,y;
        cin>>x>>y;
        add_edge(x,y),add_edge(y,x);
    }
    dfs1(r,0);
    dfs2(r,r);
    build(1,1,n);
    while (m--){
        int t,x,y,z;
        cin>>t;
        if (t==1){
            cin>>x>>y>>z;
        //    update_path(x,y,z%mod);
        }
        if (t==2){
            cin>>x>>y;
        //    cout<<query_sum(x,y)%mod<<endl;
        }
        if (t==3){
            cin>>x>>y;
        //    update(1,1,n,id[x],id[x]+size[x]-1,y%mod);
        }
        if (t==4){
            cin>>x;
            //cout<<query(1,1,n,id[x],size[x]+id[x]-1)%mod<<endl;
        }
    }
    return 0;
}
2024/8/1 22:29
加载中...