19pts,AC#1#11,3TLE,其余WA

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

Miangoa @ 2023-11-12 17:12:51

#include<bits/stdc++.h>
#define int long long

using namespace std;

int n,m,mod;
struct tree {
    int r,num[100010],h[100010],e[200010][2],cnt;
    int muc[100010],dep[100010],son[100010],nbh[100010],cntn,top[100010],fat[100010];
    void add(int x,int y) {
        e[++cnt][0]=y;
        e[cnt][1]=h[x];
        h[x]=cnt;
        e[++cnt][0]=x;
        e[cnt][1]=h[y];
        h[y]=cnt;
    }
    void init(int p,int f) {
        muc[p]=1;
        int ma=0;
        for(register int i=h[p]; i; i=e[i][1])
            if(e[i][0]!=f) {
                init(e[i][0],p);
                muc[p]+=muc[e[i][0]];
                if(muc[e[i][0]]>ma)
                    ma=muc[e[i][0]],son[p]=e[i][0];
            }
    }
    void reset(int p,int f) {
        nbh[p]=++cntn;
        if(son[p])
            reset(son[p],p);
        for(register int i=h[p]; i; i=e[i][1])
            if(e[i][0]!=f&&e[i][0]!=son[p]) {
                reset(e[i][0],p);
            }
    }
    void reinit(int p,int f) {
        fat[nbh[p]]=nbh[f],dep[nbh[p]]=dep[nbh[f]]+1,muc[nbh[p]]=1;
        if(!top[nbh[p]])
            top[nbh[p]]=nbh[p];
        if(son[p])
            reinit(son[p],p),muc[nbh[p]]+=muc[nbh[son[p]]],top[nbh[son[p]]]=top[nbh[p]];
        for(register int i=h[p]; i; i=e[i][1])
            if(e[i][0]!=f&&e[i][0]!=son[p]) {
                reinit(e[i][0],p);
                muc[nbh[p]]+=muc[nbh[e[i][0]]];
            }
    }
} tree;
struct xds {
    int num[100010],l[400010],r[400010],v[400010],tag[400010];
    void build(int p,int lef,int rig) {
        l[p]=lef,r[p]=rig;
        if(lef==rig)
            v[p]=num[lef]%mod;
        else {
            build(p*2,lef,(lef+rig)/2);
            build(p*2+1,(lef+rig)/2+1,rig);
            v[p]=v[p*2]+v[p*2+1],v[p]%=mod;
        }
    }
    void down(int p) {
        tag[p*2]+=tag[p],tag[p*2+1]+=tag[p];
        tag[p*2]%=mod,tag[p*2+1]%=mod;
        v[p*2]+=tag[p]*(r[p*2]-l[p*2]+1),v[p*2+1]+=tag[p]*(r[p*2+1]-l[p*2+1]+1);
        v[p*2]%=mod,v[p*2+1]%=mod;
        tag[p]=0;
    }
    int que(int p,int lef,int rig) {
        if(lef<=l[p]&&rig>=r[p])
            return v[p]%mod;
        down(p);
        int ret=0;
        if(lef<=(l[p]+r[p])/2)
            ret+=que(p*2,lef,rig);
        if(rig>(l[p]+r[p])/2)
            ret+=que(p*2+1,lef,rig);
        return ret%mod;
    }
    void cha(int p,int lef,int rig,int k) {
        if(lef<=l[p]&&rig>=r[p]) {
            tag[p]+=k,tag[p]%=mod;
            v[p]+=k*(r[p]-l[p]+1),v[p]%=mod;
        } else {
            down(p);
            if(lef<=(l[p]+r[p])/2)
                cha(p*2,lef,rig,k);
            if(rig>(l[p]+r[p])/2)
                cha(p*2+1,lef,rig,k);
            v[p]=v[p*2]+v[p*2+1],v[p]%=mod;
        }
    }
} all;

inline int read() {
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
        f=(ch=='-'?-1:f),ch=getchar();
    while(ch>='0'&&ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return f*x;
}

signed main() {
    n=read(),m=read(),tree.r=read(),mod=read();
    for(register int i=1; i<=n; i++)
        tree.num[i]=read()%mod;
    for(register int i=1; i<n; i++)
        tree.add(read(),read());
    tree.init(tree.r,0);
    tree.reset(tree.r,0);
    tree.reinit(tree.r,0);
    for(register int i=1; i<=n; i++)
        all.num[tree.nbh[i]]=tree.num[i];
    all.build(1,1,n);
    while(m--) {
        int op=read();
        if(op==1) {
            int x=tree.nbh[read()],y=tree.nbh[read()],z=read()%mod;
            while(tree.top[x]!=tree.top[y]) {
                if(tree.dep[tree.top[x]]<tree.dep[tree.top[y]])
                    swap(x,y);
                all.cha(1,tree.top[x],x,z);
                x=tree.fat[tree.top[x]];
            }
            if(tree.dep[x]>tree.dep[y])
                swap(x,y);
            all.cha(1,x,y,z);
        }
        if(op==2) {
            int x=tree.nbh[read()],y=tree.nbh[read()];
            int ans=0;
            while(tree.top[x]!=tree.top[y]) {
                if(tree.dep[tree.top[x]]<tree.dep[tree.top[y]])
                    swap(x,y);
                ans+=all.que(1,tree.top[x],x),ans%=mod;
                x=tree.fat[tree.top[x]];
            }
            if(tree.dep[x]<tree.dep[y])
                swap(x,y);
            ans+=all.que(1,x,y);
            printf("%lld\n",ans%mod);
        }
        if(op==3) {
            int x=tree.nbh[read()],z=read()%mod;
            all.cha(1,x,x+tree.muc[x]-1,z);
        }
        if(op==4) {
            int x=tree.nbh[read()];
            printf("%lld\n",all.que(1,x,x+tree.muc[x]-1));
        }
    }
}

by Miangoa @ 2023-11-12 17:16:34

补充:

if(tree.dep[x]<tree.dep[y])
    swap(x,y);

改符号会换点AC


|