求助,调了半天也不知道为什么RE

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

R_aier @ 2023-07-24 22:13:09

#include <bits/stdc++.h>
#define LOCAL
#define INPUTFILE "1.in"
#define OUTPUTFILE "1.out"
using namespace std;
const int maxn = 2e6 + 10;
struct edge
{
    int to,next;
    edge():next(-1){}
    edge(int to,int next):to(to),next(next){}
}e[maxn*2];

int son[maxn],top[maxn],siz[maxn],fa[maxn],dep[maxn],v[maxn],tim,cnt,head[maxn];
int id[maxn],w[maxn],tree[maxn*4],tag[maxn*4];
int n,m,mod,root;
void addedge(int u,int v)
{
    e[++cnt]=edge(v,head[u]);head[u]=cnt;
}
void dfs1(int u,int f)
{
    dep[u]=dep[f]+1;fa[u]=f;siz[u]=1;
    int maxsiz=-1;
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].to;
        if(v==f)continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>maxsiz)
        {
            son[u]=v;maxsiz=siz[v];
        }
    }
}
void dfs2(int u,int t)
{
    top[u]=t;id[u]=++tim;w[tim]=v[u];
    if(!son[u])return;
    dfs2(son[u],t);
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].to;
        if(v!=fa[u]&&v!=son[u])
            dfs2(v,v);
    }
}
void addtag(int l,int r,int p,int k)
{
    tree[p]+=(r-l+1)*k;
    tree[p]%=mod;
    tag[p]+=k;
}
void push_up(int p)
{
    tree[p]=tree[p*2]+tree[p*2+1];
    tree[p]%=mod;
}
void push_down(int l,int r,int p)
{
    if(!tag[p]) return;
    int mid=(l+r)/2;
    addtag(l,mid,p*2,tag[p]);
    addtag(mid+1,r,p*2+1,tag[p]);
    tag[p]=0;
}

void build(int l,int r,int p)
{
    if(l==r){
        tree[p]=w[l];
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,p*2);
    build(mid+1,r,p*2+1);
    push_up(p);
    tree[p]%=mod;
}
//l~r add k
void qupdate(int l,int r,int x,int y,int p,int k)
{
    if (x >= l && y <= r)
    {
        addtag(x, y, p, k);
        return;
    }
    push_down(x,y,p);
    int mid = (x + y) / 2;
    if (l <= mid)
        qupdate(l, r, x, mid, p * 2, k);
    if (r > mid)
        qupdate(l, r, mid + 1, r, p * 2 + 1, k);
    push_up(p);
}
int qquery(int l,int r,int x,int y,int p)
{
    if (x >= l && y <= r)
    {
        return tree[p]%mod;
    }
    push_down(x,y,p);
    int mid=(x+y)/2;
    int res=0;
    if (l <= mid)
        res+=qquery(l, r, x, mid, p * 2);
    if (r > mid)
        res+=qquery(l, r, mid + 1, r, p * 2 + 1);
    return res%mod;
}

void tupdate(int u,int v,int k)
{
    while (top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        qupdate(id[top[u]],id[u],1,n,1,k);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    qupdate(id[u],id[v],1,n,1,k);
}

int tquery(int u,int v)
{
    int res=0;
    while (top[u]!=top[v])
    {
        if (dep[top[u]] < dep[top[v]])
            swap(u, v);
        res+=qquery(id[top[u]], id[u], 1, n, 1);
        res%=mod;
        u = fa[top[u]];
    }
    if (dep[u] > dep[v])
        swap(u, v);
    return (qquery(id[u], id[v], 1, n, 1)+res)%mod;
}

void zupdete(int r,int k)
{
    qupdate(id[r],id[r]+siz[r]-1,1,n,1,k);
}
int zquery(int r)
{
    return (qquery(id[r],id[r]+siz[r]-1,1,n,1)%mod);
}
int main()
{
    clock_t clockf = clock();
#ifdef LOCAL
    freopen(INPUTFILE, "r", stdin);
    freopen(OUTPUTFILE, "w", stdout);
#endif
//=======================================================================================================================
    cin>>n>>m>>root>>mod;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
        scanf("%d",&v[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v);addedge(v,u);
    }
    dfs1(root,root);
    dfs2(root,root);
    build(1,n,1);
    int opt,x,y,z;
    while (m--)
    {

        scanf("%d",&opt);
        switch (opt)
        {
        case 1:{
            scanf("%d%d%d",&x,&y,&z);
            tupdate(x,y,z);
        }
            break;
        case 2:{
            scanf("%d%d",&x,&y);
            printf("%d\n",tquery(x,y));
        }
            break;
        case 3:{
            scanf("%d%d",&x,&z);
            zupdete(x,z);
        }
            break;
        case 4:{
            scanf("%d",&x);
            printf("%d\n",zquery(x));
        }
            break;
        }
    }

//=======================================================================================================================
end:
    cerr << "Time Used:" << clock() - clockf << "ms" << endl;
    return 0;
}

|