重剖写挂求调
查看原帖
重剖写挂求调
964089
run_away楼主2024/3/15 19:42

不知道为什么会RE

#include<bits/stdc++.h>
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
typedef long long ll;
using namespace std;
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
const ll maxn=1e5+5;
ll n,m,root,mod,top[maxn],dep[maxn],fa[maxn],siz[maxn],son[maxn],head[maxn],tot,dfn[maxn],id[maxn],cnt,a[maxn];
struct edge{ll to,nxt;}e[maxn<<1];
inline void add(ll u,ll v){e[++tot]=(edge){v,head[u]},head[u]=tot;}
//以下为线段树模板
struct linetree{ll v,lazy;}t[maxn<<2];
inline void buildtree(ll x,ll l,ll r){
    if(l==r){
        t[x].v=a[id[l]]%mod;
        return;
    }
    buildtree(ls,l,mid);
    buildtree(rs,mid+1,r);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline void pushdown(ll x,ll l,ll r){
    if(t[x].lazy){
        t[ls].lazy+=t[x].lazy,t[rs].lazy+=t[x].lazy;
        t[ls].v+=t[x].lazy*(mid-l+1),t[ls].v%=mod;
        t[rs].v+=t[x].lazy*(r-mid),t[rs].v%=mod;
        t[x].lazy=0;
    }
}
inline void treeupdate(ll x,ll l,ll r,ll s,ll e,ll val){
    if(s<=l&&r<=e){
        t[x].lazy+=val,t[x].lazy%=mod;
        t[x].v+=val*(r-l+1),t[x].v%=mod;
        return;
    }
    pushdown(x,l,r);
    if(mid>=s)treeupdate(ls,l,mid,s,e,val);
    if(mid<e)treeupdate(rs,mid+1,r,s,e,val);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline ll treeask(ll x,ll l,ll r,ll s,ll e){
    if(s<=l&&r<=e)return t[x].v;
    pushdown(x,l,r);
    ll ans=0;
    if(mid>=s)ans+=treeask(ls,l,mid,s,e);
    if(mid<e)ans+=treeask(rs,mid+1,r,s,e);
    return ans%mod;
}
//以上为线段树模板
//以下为重链剖分模板
inline void dfs1(ll u,ll pre){
    fa[u]=pre,siz[u]=1,dep[u]=dep[pre]+1;
    for(ll i=head[u];i;i=e[i].nxt){
        ll v=e[i].to;
        if(v==pre)continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]<siz[v])son[u]=v;
    }
}
inline void dfs2(ll u,ll tf){
    top[u]=tf,dfn[u]=++cnt,id[cnt]=u;
    if(son[u])dfs2(son[u],tf);
    for(ll i=head[u];i;i=e[i].nxt){
        ll v=e[i].to;
        if(v==fa[u]||v==son[u])continue;
        dfs2(v,v);
    }
}
// inline ll lca(ll u,ll v){
//     while(top[u]!=top[v]){
//         if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
//         u=fa[top[u]];
//     }
//     if(dep[u]>dep[v])swap(u,v);
//     return u;
// }
inline ll query(ll u,ll v){
    ll ans=0;
    while(top[u]!=top[v]){
        if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
        ans+=treeask(1,1,n,dfn[top[u]],dfn[u]),ans%=mod;
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    ans+=treeask(1,1,n,dfn[u],dfn[v]),ans%=mod;
    return ans;
}
inline void modify(ll u,ll v,ll w){
    while(top[u]!=top[v]){
        if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
        treeupdate(1,1,n,dfn[top[u]],dfn[u],w);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    treeupdate(1,1,n,dfn[u],dfn[v],w);
}
//以上为重链剖分模板
signed main(){
    n=read(),m=read(),root=read(),mod=read();
    for(ll i=1;i<=n;++i)a[i]=read();
    for(ll i=1;i<n;++i){
        ll u=read(),v=read();
        add(u,v),add(v,u);
    }
    dfs1(root,0),dfs2(root,root),buildtree(1,1,n);
    while(m--){
        ll opt=read();
        if(opt==1){
            ll x=read(),y=read(),z=read();modify(x,y,z);
        }
        else if(opt==2){
            ll x=read(),y=read();printf("%lld\n",query(x,y));
        }
        else if(opt==3){
            ll x=read(),z=read();treeupdate(1,1,n,dfn[x],dfn[x]+siz[x]-1,z%mod);
        }
        else{
            ll x=read();printf("%lld\n",treeask(1,1,n,dfn[x],dfn[x]+siz[x]-1));
        }
    }
    return 0;
}
2024/3/15 19:42
加载中...