树剖板子求助,纯度100%

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

柠檬布丁吖 @ 2023-04-02 19:58:06

//inline void dfs1(int x,int f,int deep){
//  dep[x]=deep;
//  fa[x]=f;
//  siz[x]=1;
//  int maxson=-1;
//  for(int i=beg[x];i;i=ne[i]){
//      int y=to[i];
//      if(y==f) continue;
//      dfs1(y,x,deep+1);
//      siz[x]+=siz[y];
//      if(siz[y]>maxson) son[x]=y;maxson=siz[y];
//  }
//}
//
//inline void dfs2(int x,int topf){
//  id[x]=++cnt;
//  wt[cnt]=w[x];
//  top[x]=topf;
//  if(!son[x]) return;
//  dfs2(son[x],topf);
//  for(int i=beg[x];i;i=ne[i]){
//      int y=to[i];
//      if(y==fa[x]||y==son[x]) continue;
//      dfs2(y,y);
//  }
//}

#include<bits/stdc++.h>

using namespace std;

#define ll long long
#define mid ((l+r)>>1)
#define len (r-l+1)

inline int read() {
    int ret=0,f=1;
    char c=getchar();
    for(; c<'0'||c>'9'; c=getchar()) if(c=='-') c=getchar();
    for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
    return ret*f;
}

int n,m,r,mod;
const int maxn=2e6+55;

int e,beg[maxn],nex[maxn],to[maxn],w[maxn],wt[maxn];

int a[maxn<<2],laz[maxn<<2];

int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
int res=0;

inline void add(int x,int y) {
    to[++e]=y;
    nex[e]=beg[x];
    beg[x]=e;
}

inline void dfs1(int x,int f,int deep) {
    dep[x]=deep;
    fa[x]=f;
    siz[x]=1;
    int maxson=-1;
    for(int i=beg[x]; i; i=nex[x]) {
        int y=to[i];
        if(y==f) continue;
        dfs1(y,x,deep+1);
        siz[x]+=siz[y];
        if(siz[y]>maxson) son[x]=y;
        maxson=siz[y];
    }
}

inline void dfs2(int x,int topf) {
    id[x]=++cnt;
    wt[cnt]=w[x];
    top[x]=topf;
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(int i=beg[x]; i; i=nex[i]) {
        int y=to[i];
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y,y);
    }
}

inline void build(int rt,int l,int r) {
    if(l==r) {
        a[rt]=wt[l];
        if(a[rt]>mod) a[rt]%=mod;
        return;
    }

    build(rt<<1,l,mid);
    build(rt<<1||1,mid+1,r);
    a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}

void pushdown(int rt,int lenn) {
    laz[rt<<1]+=laz[rt];
    laz[rt<<1|1]+=laz[rt];
    a[rt<<1]+=laz[rt]*(lenn-(lenn>>1));
    a[rt<<1|1]+=laz[rt]*(lenn>>1);
    a[rt<<1]%=mod;
    a[rt<<1|1]%=mod;
    laz[rt]=0;
}

inline void update(int rt,int l,int r,int L,int R,int k) {
    if(L<=l&&r<=R) {
        laz[rt]+=k;
        a[rt]+=k*len;
    } else {
        if(laz[rt]) pushdown(rt,len);

        if(L<=mid) update(rt<<1,l,mid,L,R,k);

        if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);

        a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
    }
}

inline void uprange(int x,int y,int k) {
    k%=mod;
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(1,1,n,id[top[x]],id[x],k);
        x=fa[top[x]];
    }

    if(dep[x]>dep[y]) swap(x,y);
    update(1,1,n,id[x],id[y],k);
}

inline void query(int rt,int l,int r,int L,int R) {
    if(L<=l&&r<=R) {
        res+=a[rt];
        res%=mod;
        return;
    } else {
        if(laz[rt]) pushdown(rt,len);
        if(L<=mid) query(rt<<1,l,mid,L,R);
        if(R>mid) query(rt<<1|1,mid+1,r,L,R);
    }
}

inline int qrange(int x,int y) {
    int ans=0;
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        res=0;
        query(1,1,n,id[top[x]],id[x]);
        ans+=res;
        ans%=mod;
        x=fa[top[x]];
    }

    if(dep[x]>dep[y]) swap(x,y);
    res=0;
    query(1,1,n,id[x],id[y]);
    ans+=res;
    return ans%mod;
}

inline void upson(int x,int k) {
    update(1,1,n,id[x],id[x]+siz[x]-1,k);
}

inline int qson(int x) {
    res=0;
    query(1,1,n,id[x],id[x]+siz[x]-1);
    return res;
}

signed main(void) {

    n=read();
    m=read();
    r=read();
    mod=read();

    for(int i=1; i<=n; i++) {
        w[i]=read();
    }

    for(int i=1; i<n-1; i++) {
        int a,b;
        a=read();
        b=read();
        add(a,b);
        add(b,a);
    }

    dfs1(r,0,1);
    dfs2(r,r);

    build(1,1,n);

    while(m--) {
        int k,x,y,z;
        k=read();
        if(k==1) {
            x=read();
            y=read();
            z=read();
            uprange(x,y,z);
        }

        if(k==2) {
            x=read();
            y=read();
            printf("%d\n",qrange(x,y));
        }

        if(k==3) {
            x=read();
            z=read();

            upson(x,y);
        }

        if(k==4) {
            x=read();
            printf("%d\n",qson(x));
        }
    }

    return 0;
}

by Lucky_Luo @ 2023-04-02 20:24:04

if(siz[y]>maxson) son[x]=y;
        maxson=siz[y];

要写成

if(siz[y]>maxson) 
{
    son[x]=y;
    maxson=siz[y];
}

by Lucky_Luo @ 2023-04-02 20:26:25

另外,操作3的参数传错了


by Lucky_Luo @ 2023-04-02 20:27:47

还有一些值更新之后没有取模


by 柠檬布丁吖 @ 2023-04-02 20:43:02

@Lucky_Luo

基本上改了一下。还是不行。

#include<bits/stdc++.h>

using namespace std;

#define ll long long
#define mid ((l+r)>>1)
#define len (r-l+1)

inline int read() {
    int ret=0,f=1;
    char c=getchar();
    for(; c<'0'||c>'9'; c=getchar()) if(c=='-') c=getchar();
    for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
    return ret*f;
}

int n,m,r,mod;
const int maxn=2e6+55;

int e,beg[maxn],nex[maxn],to[maxn],w[maxn],wt[maxn];

int a[maxn<<2],laz[maxn<<2];

int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
int res=0;

inline void add(int x,int y) {
    to[++e]=y;
    nex[e]=beg[x];
    beg[x]=e;
}

inline void dfs1(int x,int f,int deep) {
    dep[x]=deep;
    fa[x]=f;
    siz[x]=1;
    int maxson=-1;
    for(int i=beg[x]; i; i=nex[x]) {
        int y=to[i];
        if(y==f) continue;
        dfs1(y,x,deep+1);
        siz[x]+=siz[y];
        if(siz[y]>maxson){
            son[x]=y;maxson=siz[y];
        } 
    }
}

inline void dfs2(int x,int topf) {
    id[x]=++cnt;
    wt[cnt]=w[x];
    top[x]=topf;
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(int i=beg[x]; i; i=nex[i]) {
        int y=to[i];
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y,y);
    }
}

inline void build(int rt,int l,int r) {
    if(l==r) {
        a[rt]=wt[l];
        if(a[rt]>mod) a[rt]%=mod;
        return;
    }

    build(rt<<1,l,mid);
    build(rt<<1||1,mid+1,r);
    a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}

void pushdown(int rt,int lenn) {
    laz[rt<<1]+=laz[rt];
    laz[rt<<1|1]+=laz[rt];
    a[rt<<1]+=laz[rt]%mod*(lenn-(lenn>>1))%mod;
    a[rt<<1|1]+=laz[rt]%mod*(lenn>>1)%mod;
    a[rt<<1]%=mod;
    a[rt<<1|1]%=mod;
    laz[rt]=0;
}

inline void update(int rt,int l,int r,int L,int R,int k) {
    if(L<=l&&r<=R) {
        laz[rt]+=k;
        a[rt]+=k*len%mod;
    } else {
        if(laz[rt]) pushdown(rt,len);

        if(L<=mid) update(rt<<1,l,mid,L,R,k);

        if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);

        a[rt]=(a[rt<<1]%mod+a[rt<<1|1]%mod)%mod;
    }
}

inline void uprange(int x,int y,int k) {
    k%=mod;
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(1,1,n,id[top[x]],id[x],k);
        x=fa[top[x]];
    }

    if(dep[x]>dep[y]) swap(x,y);
    update(1,1,n,id[x],id[y],k);
}

inline void query(int rt,int l,int r,int L,int R) {
    if(L<=l&&r<=R) {
        res+=a[rt];
        res%=mod;
        return;
    } else {
        if(laz[rt]) pushdown(rt,len);
        if(L<=mid) query(rt<<1,l,mid,L,R);
        if(R>mid) query(rt<<1|1,mid+1,r,L,R);
    }
}

inline int qrange(int x,int y) {
    int ans=0;
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        res=0;
        query(1,1,n,id[top[x]],id[x]);
        ans=res%mod+ans%mod;
        ans%=mod;
        x=fa[top[x]];
    }

    if(dep[x]>dep[y]) swap(x,y);
    res=0;
    query(1,1,n,id[x],id[y]);
    ans=res%mod+ans%mod;
    return ans%mod;
}

inline void upson(int x,int k) {
    update(1,1,n,id[x],id[x]+siz[x]-1,k);
}

inline int qson(int x) {
    res=0;
    query(1,1,n,id[x],id[x]+siz[x]-1);
    return res%mod;
}

signed main(void) {

    n=read();
    m=read();
    r=read();
    mod=read();

    for(int i=1; i<=n; i++) {
        w[i]=read();
    }

    for(int i=1; i<n-1; i++) {
        int a,b;
        a=read();
        b=read();
        add(a,b);
        add(b,a);
    }

    dfs1(r,0,1);
    dfs2(r,r);

    build(1,1,n);

    while(m--) {
        int k,x,y,z;
        k=read();
        if(k==1) {
            x=read();
            y=read();
            z=read();
            uprange(x,y,z);
        }

        if(k==2) {
            x=read();
            y=read();
            printf("%d\n",qrange(x,y));
        }

        if(k==3) {
            x=read();
            y=read();

            upson(x,y);
        }

        if(k==4) {
            x=read();
            printf("%d\n",qson(x));
        }
    }

    return 0;
}

|