28pts,刚学OI 0.1ns,悬关求调
查看原帖
28pts,刚学OI 0.1ns,悬关求调
749175
114514xxx楼主2024/10/29 22:22

Record

#include<bits/stdc++.h>
#define int long long
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N=2e5+205;
int a[N];
int n,m,root,mod;
int fa[N],dep[N],siz[N],son[N];
int dfn[N],top[N],rnk[N];
struct Edge{
    int to,next;
}edge[N];
struct SGT{
    int l,r,sum,add;
}t[N<<2];
inline int read(){
    int x=0,f=1;
    char c=getchar_unlocked();
    while(!isdigit(c)){
        if(c=='-')f*=-1;
        c=getchar_unlocked();
    }
    while(isdigit(c)){
        x=(x<<3)+(x<<1)+(c^48);
        c=getchar_unlocked();
    }
    return x*f;
}
inline void update(int p){t[p].sum=(t[ls].sum%mod+t[rs].sum%mod)%mod;}
inline void build(int l,int r,int p){
    t[p].l=l,t[p].r=r;
    if(l==r){
        t[p].sum=a[rnk[l]]%mod;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,ls);
    build(mid+1,r,rs);
    update(p);
}
inline void spread(int p){
    t[p].add%=mod;
    t[ls].sum=(t[ls].sum%mod+t[p].add%mod)%mod;
    t[rs].sum=(t[rs].sum%mod+t[p].add%mod)%mod;
    t[ls].add=(t[ls].add%mod+t[p].add%mod)%mod;
    t[rs].add=(t[rs].add%mod+t[p].add%mod)%mod;
    t[p].add=0;
    return;
}
inline void modify(int l,int r,int p,int k){
    k%=mod;
    if(t[p].l>=l&&t[p].r<=r){
        t[p].sum+=k;
        t[p].add+=k;
        t[p].sum%=mod;
        t[p].add%=mod;
        return;
    }
    spread(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid)modify(l,r,ls,k);
    if(r>mid)modify(l,r,rs,k);
    update(p);
}
inline int query(int l,int r,int p){
    int ans=0;
    if(t[p].l>=l&&t[p].r<=r)
        return t[p].sum%mod;
    spread(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid)ans+=query(l,r,ls),ans%=mod;
    if(r>mid)ans+=query(l,r,rs),ans%=mod;
    update(p);
    ans%=mod;
    return ans;
}
int head[N],cnt;
inline void add(int x,int y){
    edge[++cnt].to=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
inline void dfs1(int u,int f){
    fa[u]=f;
    dep[u]=dep[f]+1;
    siz[u]=1;son[u]=-1;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(v==f)continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(son[u]==-1||siz[son[u]]<=siz[v])son[u]=v;
    }
}
int tot;
inline void dfs2(int u,int topf){
    top[u]=topf;
    ++tot;
    dfn[u]=tot;
    rnk[tot]=u;
    if(son[u]==-1)return;
    dfs2(son[u],topf);
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa[u])continue;
        if(v!=son[u]&&v!=fa[u])dfs2(v,v);
    }
}
inline void Pathmodify(int u,int v,int k){
    k%=mod;
    //if(dep[top[u]]<dep[top[v]])swap(u,v);
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        modify(dfn[top[u]],dfn[u],1,k);
        u=fa[top[u]];
        if(dep[top[u]]<dep[top[v]])swap(u,v);
    }
    if(dep[top[u]]<dep[top[u]])swap(u,v);
    modify(dep[u],dep[v],1,k);
}
inline int Pathquery(int u,int v){
    int ans=0;
    if(dep[top[u]]<dep[top[v]])swap(u,v);
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        ans+=query(dfn[top[u]],dfn[u],1);
        ans%=mod;
        u=fa[top[u]];
        if(dep[top[u]]<dep[top[v]])swap(u,v);
    }
    if(dep[top[u]]<dep[top[u]])swap(u,v);
    ans+=query(dfn[u],dfn[v],1)%mod;
    ans%=mod;
    return ans;
}
inline void Nodemodify(int x,int k){
    k%=mod;
    modify(dfn[x],dfn[x]+siz[x]-1,1,k);
    return;
}
inline int Nodequery(int x){
    return query(dfn[x],dfn[x]+siz[x]-1,1)%mod;
}
signed main(){
    //freopen("P3384_1.in","r",stdin);
    n=read(),m=read(),root=read(),mod=read();
    for(int i=1;i<=n;i++)
        a[i]=read(),a[i]%=mod;
    int u,v;
    for(int i=1;i<=n;i++)
        son[i]=-1;
    for(int i=1;i<n;i++){
        u=read(),v=read();
        add(u,v),add(v,u);
    }
    int opt,x,y,z;
    dfs1(root,0);
    dfs2(root,root);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        opt=read();
        switch(opt){
            case 1:{
                x=read(),y=read(),z=read();
                Pathmodify(x,y,z);
                break;
            }
            case 2:{
                x=read(),y=read();
                cout<<Pathquery(x,y)%mod<<"\n";
                break;
            }
            case 3:{
                x=read(),z=read();
                Nodemodify(x,z);
                break;
            }
            case 4:{
                x=read();
                cout<<Nodequery(x)%mod<<"\n";
                break;
            }
        }
    }
}

2024/10/29 22:22
加载中...