萌新初学树剖,样例没过求调

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

foryou_ @ 2023-10-07 14:17:08

RT

代码:

#include<bits/stdc++.h>
using namespace std;

int n,m,r,p,tot;
int w[100031],ww[100031];
vector<int> G[100031];
int dep[100031],fa[100031],sz[100031],son[100031],top[100031],id[100031];
struct SegmentTree{
    int l,r,sum,add;
}t[400031];

void bld(int p,int l,int r){
    t[p].l=l; t[p].r=r;
    if(l==r){ t[p].sum=ww[l]%p; return; }
    int mid=(l+r)/2;
    bld(p*2,l,mid);
    bld(p*2+1,mid+1,r);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%p;
}
void spd(int p){
    if(t[p].add){
        t[p*2].sum+=t[p].add*(t[p*2].r-t[p*2].l+1);
        t[p*2+1].sum+=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);
        t[p*2].add+=t[p].add;
        t[p*2+1].add+=t[p].add;
        t[p].add=0;
    }
}
void upd(int p,int l,int r,int d){
    if(l<=t[p].l&&r>=t[p].r){
        t[p].sum+=(int)d*(t[p].r-t[p].l+1);
        t[p].add+=d;
        return;
    }
    spd(p);
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) upd(p*2,l,r,d);
    if(r>mid) upd(p*2+1,l,r,d);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%p;
}
int qry(int p,int l,int r){
    if(l<=t[p].l&&r>=t[p].r) return t[p].sum;
    spd(p);
    int val=0;
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) val+=qry(p*2,l,r);
    if(r>mid) val+=qry(p*2+1,l,r);
    return val;
}
void updRange(int x,int y,int z){
    z%=p;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        upd(1,id[top[x]],id[x],z),x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    upd(1,id[x],id[y],z);
}
int qryRange(int x,int y){
    int ans=0;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=qry(1,id[top[x]],id[x]),ans%=p,x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans+=qry(1,id[x],id[y]),ans%=p;
    return ans;
}
void updSon(int x,int y){
    upd(1,id[x],id[x]+sz[x]-1,y);
}
int qrySon(int x){
    return qry(1,id[x],id[x]+sz[x]-1)%p;
}
void dfs1(int x,int f,int depth){
    dep[x]=depth,fa[x]=f,sz[x]=1;
    int maxson=-1e9;
    for(auto i:G[x]){
        if(i==f) continue;
        dfs1(i,x,depth+1);
        sz[x]+=sz[i];
        if(sz[i]>maxson) maxson=sz[i],son[x]=i;
    }
}
void dfs2(int x,int tp){
    id[x]=++tot,ww[tot]=w[x],top[x]=tp;
    if(!son[x]) return; dfs2(son[x],tp);
    for(auto i:G[x]){
        if(i==son[x]||i==fa[x]) continue;
        dfs2(i,i);
    }
}

int main(){
    cin>>n>>m>>r>>p;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1,u,v;i<n;i++){
        cin>>u>>v;
        G[u].push_back(v),G[v].push_back(u);
    }
    dfs1(r,0,1),dfs2(r,r);
    bld(1,1,n);
    while(m--){
        int op,x,y,z;
        cin>>op;
        if(op==1) cin>>x>>y>>z,updRange(x,y,z);
        else if(op==2) cin>>x>>y,cout<<qryRange(x,y)<<'\n';
        else if(op==3) cin>>x>>z,updSon(x,z);
        else cin>>x,cout<<qrySon(x)<<'\n';
    }
    return 0;
}

by MatrixGroup @ 2023-10-07 15:28:34

void upd(int p,int l,int r,int d){
    if(l<=t[p].l&&r>=t[p].r){
        t[p].sum+=(int)d*(t[p].r-t[p].l+1);
        t[p].add+=d;
        return;
    }
    spd(p);
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) upd(p*2,l,r,d);
    if(r>mid) upd(p*2+1,l,r,d);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%p;
}

你家线段树模编号?


by MatrixGroup @ 2023-10-07 15:30:00

@XOF


by Nobelium_255 @ 2023-10-07 15:31:48

局部变量和全局变量重名是个坏习惯(确信


by foryou_ @ 2023-10-07 15:42:08

@Anomynous 感谢。但改了还是 28 分。


by MatrixGroup @ 2023-10-07 15:43:11

@XOF 你的程序有很多溢出的地方


by foryou_ @ 2023-10-07 15:45:51

@Anomynous 额但我开了四倍空间之后仍然没有效果qwq。


by MatrixGroup @ 2023-10-07 15:48:38

@XOF 溢出是 int 溢出.换句话说,很多的地方你没有取模


by foryou_ @ 2023-10-07 16:01:46

@Anomynous

按照您说的改了,但是无任何效果。麻烦您再帮我看一下代码的问题qwq。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int n,m,r,mod,tot;
int w[400031],ww[400031];
vector<int> G[400031];
int dep[400031],fa[400031],sz[400031],son[400031],top[400031],id[400031];
struct SegmentTree{
    int l,r,sum,add;
}t[800031];

void bld(int p,int l,int r){
    t[p].l=l; t[p].r=r;
    if(l==r){ t[p].sum=ww[l]%mod; return; }
    int mid=(l+r)/2;
    bld(p*2,l,mid);
    bld(p*2+1,mid+1,r);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
void spd(int p){
    if(t[p].add){
        t[p*2].sum+=t[p].add*(t[p*2].r-t[p*2].l+1);
        t[p*2+1].sum+=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);
        t[p*2].sum%=mod,t[p*2+1].sum%=mod;
        t[p*2].add+=t[p].add,t[p*2].add%=mod;
        t[p*2+1].add+=t[p].add,t[p*2+1].add%=mod;
        t[p].add=0;
    }
}
void upd(int p,int l,int r,int d){
    if(l<=t[p].l&&r>=t[p].r){
        t[p].sum+=(int)d*(t[p].r-t[p].l+1),t[p].sum%=mod;
        t[p].add+=d,t[p].add%=mod;
        return;
    }
    spd(p);
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) upd(p*2,l,r,d);
    if(r>mid) upd(p*2+1,l,r,d);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
int qry(int p,int l,int r){
    if(l<=t[p].l&&r>=t[p].r) return t[p].sum%mod;
    spd(p);
    int val=0;
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) val+=qry(p*2,l,r),val%=mod;
    if(r>mid) val+=qry(p*2+1,l,r),val%=mod;
    return val%mod;
}
void updRange(int x,int y,int z){
    z%=mod;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        upd(1,id[top[x]],id[x],z),x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    upd(1,id[x],id[y],z);
}
int qryRange(int x,int y){
    int ans=0;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=qry(1,id[top[x]],id[x]),ans%=mod,x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans+=qry(1,id[x],id[y]),ans%=mod;
    return ans;
}
void updSon(int x,int y){
    upd(1,id[x],id[x]+sz[x]-1,y);
}
int qrySon(int x){
    return qry(1,id[x],id[x]+sz[x]-1)%mod;
}
void dfs1(int x,int f,int depth){
    dep[x]=depth,fa[x]=f,sz[x]=1;
    int maxson=-1e9;
    for(auto i:G[x]){
        if(i==f) continue;
        dfs1(i,x,depth+1);
        sz[x]+=sz[i];
        if(sz[i]>maxson) maxson=sz[i],son[x]=i;
    }
}
void dfs2(int x,int tp){
    id[x]=++tot,ww[tot]=w[x],top[x]=tp;
    if(!son[x]) return; dfs2(son[x],tp);
    for(auto i:G[x]){
        if(i==son[x]||i==fa[x]) continue;
        dfs2(i,i);
    }
}

signed main(){
    cin>>n>>m>>r>>mod;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1,u,v;i<n;i++){
        cin>>u>>v;
        G[u].push_back(v),G[v].push_back(u);
    }
    dfs1(r,0,1),dfs2(r,r);
    bld(1,1,n);
    while(m--){
        int op,x,y,z;
        cin>>op;
        if(op==1) cin>>x>>y>>z,updRange(x,y,z);
        else if(op==2) cin>>x>>y,cout<<qryRange(x,y)%mod<<'\n';
        else if(op==3) cin>>x>>z,updSon(x,z);
        else cin>>x,cout<<qrySon(x)%mod<<'\n';
    }
    return 0;
}

by MatrixGroup @ 2023-10-07 16:20:17

@XOF

if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=qry(1,id[top[x]],id[x]),ans%=p,x=fa[top[x]];
    }

你家树剖 if?


by foryou_ @ 2023-10-07 16:36:10

@Anomynous 过了,拜谢大佬 /bx/bx


|