28pts AC 5,8,11其余WA 玄关

P3384 【模板】重链剖分/树链剖分

W_Sibo @ 2024-08-21 14:16:12

#include <iostream>
using namespace std;
typedef long long ll;
const ll N=100005;
ll n,m,r,mod;
ll a[N];
ll siz[N],fa[N],dep[N],seg[N],rev[N],top[N],son[N];
ll hd[N],nt[2*N],v[2*N],cnt=1;
ll tr[N*4],mk[N*4];
inline void add(ll x,ll y){
    v[++cnt]=y;
    nt[cnt]=hd[x];
    hd[x]=cnt;
}
inline void dfs1(ll u,ll f){
    siz[u]=1;
    fa[u]=f;
    dep[u]=dep[f]+1;
    for(ll i=hd[u];i;i=nt[i]){
        ll y=v[i];
        if(y!=f){
            dfs1(y,u);
            siz[u]+=siz[y];
            if(siz[y]>siz[son[u]]){
                son[u]=y;
            }
        }
    }
}
inline void dfs2(ll u,ll f){
    if(son[u]){
        seg[son[u]]=++seg[0];
        top[son[u]]=top[u];
        rev[seg[0]]=son[u];
        dfs2(son[u],u);
    }
    for(ll i=hd[u];i;i=nt[i]){
        ll y=v[i];
        if(!top[y]){
            seg[y]=++seg[0];
            rev[seg[0]]=y;
            top[y]=y;
            dfs2(y,u);
        }
    }
}
inline void build(ll l,ll r,ll p){
    if(l==r){
        tr[p]=a[rev[l]];
    }else{
        ll mid=(l+r)/2;
        build(l,mid,p*2);
        build(mid+1,r,p*2+1);
        tr[p]=tr[p*2]+tr[p*2+1];
    }
}
inline void push_down(ll p,ll len){
    mk[p*2]+=mk[p];
    mk[p*2+1]+=mk[p];
    tr[p*2]+=mk[p]*(len-len/2);
    tr[p*2+1]+=mk[p]*(len/2);
    mk[p]=0;
}
inline void update(ll l,ll r,ll d,ll p,ll cl,ll cr){
    if(cl>r||cr<l){
        return;
    }else if(cl>=l&&cr<=r){
        tr[p]+=(cr-cl+1)*d;
        if(cr>cl){
            mk[p]+=d;
        }
    }else{
        ll mid=(cl+cr)/2;
        push_down(p,cr-cl+1);
        update(l,r,d,p*2,cl,mid);
        update(l,r,d,p*2+1,mid+1,cr);
        tr[p]=tr[p*2]+tr[p*2+1];
    }
}
inline ll query(ll l,ll r,ll p,ll cl,ll cr){
    if(cl>r||cr<l){
        return 0;
    }else if(cl>=l&&cr<=r){
        return tr[p];
    }else{
        ll mid=(cl+cr)/2;
        push_down(p,cr-cl+1);
        return (ll)(query(l,r,p*2,cl,mid)+query(l,r,p*2+1,mid+1,cr));
    }
}
inline void op1(ll x,ll y,ll z){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            swap(x,y);
        }
        update(seg[top[x]],seg[x],z,1,1,n);
        x=fa[top[x]]; 
    }
    if(dep[x]>dep[y]){
        swap(x,y);
    } 
    update(seg[x],seg[y],z,1,1,n);
}
inline ll op2(ll x,ll y){
    ll ans=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            swap(x,y);
        }
        ans=(ans+query(seg[top[x]],seg[x],1,1,n));
        x=fa[top[x]]; 
    }
    if(dep[x]>dep[y]){
        swap(x,y);
    } 
    ans=(ans+query(seg[x],seg[y],1,1,n));
    return ans;
}
inline void op3(ll x,ll y){
    update(seg[x],seg[x]+siz[x]-1,y,1,1,n);
}
inline ll op4(ll x){
    return query(seg[x],seg[x]+siz[x]-1,1,1,n);
}
int main(){
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    cin>>n>>m>>r>>mod;
    for(ll i=1;i<=n;i++){
        cin>>a[i];
    }
    for(ll i=1;i<n;i++){
        ll x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    dfs1(r,0);
    seg[r]=++seg[0];
    top[r]=r;
    rev[r]=1;
    dfs2(r,0);
    build(1,n,1);
    for(ll i=1;i<=m;i++){
        ll k;
        cin>>k;
        if(k==1){
            ll x,y,z;
            cin>>x>>y>>z;
            op1(x,y,z);
        }else if(k==2){
            ll x,y;
            cin>>x>>y;
            cout<<op2(x,y)%mod<<'\n';
        }else if(k==3){
            ll x,y;
            cin>>x>>y;
            op3(x,y);
        }else{
            ll x;
            cin>>x;
            cout<<op4(x)%mod<<'\n';
        }
    } 
}

by W_Sibo @ 2024-08-21 14:27:03

input:
8 10 2 448348 
458 718 447 857 633 264 238 944  
1 2 
2 3 
3 4 
6 2 
1 5 
5 7 
8 6 
3 7 611 
4 6 
3 1 267 
3 2 111 
1 6 3 153 
3 7 673 
4 8  
2 6 1 
4 7 
3 4 228 

正确output:
1208
1055
2346
1900

我的output:
1208
1055
1628
1900

by W_Sibo @ 2024-08-21 14:31:57

大概率是op2的问题


by W_Sibo @ 2024-08-21 15:23:04

已过,此贴结


by _zhengzachary @ 2024-08-24 09:25:12

又调了几个小时?罚了多少时?


|