我是 RE 仙人 10pts求调

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

_Kamisato_Ayaka_ @ 2024-11-25 14:35:58

只有最后一个点 A 了

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 33;

inline int read()
{
    int f = 1,res = 0;
    char ch = getchar();
    while(!isdigit(ch)){if(ch == '-') f = -1;ch = getchar();}
    while(isdigit(ch)){res = (res << 1) + (res << 3) + (ch ^ 48);ch = getchar();}
    return res * f;
}

vector <int> tree[MAXN];
int n,m,root,p,ind;
int depth[MAXN],dfn[MAXN],son[MAXN],siz[MAXN],arr[MAXN],newarr[MAXN],top[MAXN],fath[MAXN];

void dfs1(int u,int fa)
{
    depth[u] = depth[fa] + 1;
    fath[u] = fa;
    siz[u] = 1;
    int hson = -33;
    for(int i = 0;i < tree[u].size();i ++)
    {
        int v = tree[u][i];
        if(v == fa) continue;
        dfs1(v,u);
        siz[u] += siz[v];
        if(siz[v] > hson)
        {
            son[u] = v;
            hson = siz[v];
        }
    }
}

void dfs2(int u,int xtop)
{
    dfn[u] = ++ ind;
    newarr[ind] = arr[u];
    top[u] = xtop;
    if(!son[u]) return;
    dfs2(son[u],xtop);
    for(int i = 0;i < tree[u].size();i ++)
    {
        int v = tree[u][i];
        if(v == fath[u] || v == son[u]) continue;
        dfs2(v,v);
    }
}

struct node{
    int l,r,lazy,val,len;
}tr[MAXN << 2];

void pushup(int rt){tr[rt].val = (tr[rt << 1].val + tr[rt << 1 | 1].val) % p;}

void pushdown(int rt)
{
    if(tr[rt].lazy)
    {
        tr[rt << 1].val = (tr[rt << 1].val + tr[rt].lazy * tr[rt << 1].len) % p;
        tr[rt << 1 | 1].val = (tr[rt << 1 | 1].val + tr[rt].lazy * tr[rt << 1 | 1].len) % p;
        tr[rt << 1].lazy = (tr[rt << 1].lazy + tr[rt].lazy) % p;
        tr[rt << 1 | 1].lazy = (tr[rt << 1 | 1].lazy + tr[rt].lazy) % p;
        tr[rt].lazy = 0;
    }
}
void build(int l,int r,int rt)
{
    tr[rt].l = l,tr[rt].r = r;
    tr[rt].len = r - l + 1;
    if(l == r)
    {
        tr[rt].val = newarr[l] % p;
        return;
    }
    int mid = l + r >> 1;
    build(l,mid,rt << 1);
    build(mid + 1,r,rt << 1 | 1);
    pushup(rt);
}
void update(int ql,int qr,int k,int rt)
{
    int l = tr[rt].l,r = tr[rt].r;
    if(ql <= l && qr >= r)
    {
        tr[rt].val = (tr[rt].val + tr[rt].len * k) % p;
        tr[rt].lazy = (tr[rt].lazy + k) % p;
        return;
    }
    pushdown(rt);
    int mid = l + r >> 1;
    if(ql <= mid)
        update(ql,qr,k,rt << 1);
    if(qr > mid)
        update(ql,qr,k,rt << 1 | 1);
    pushup(rt);
}
int query(int ql,int qr,int rt)
{
    int l = tr[rt].l,r = tr[rt].r,ret = 0;
    if(ql <= l && qr >= r)
        return tr[rt].val;
    int mid = l + r >> 1;
    pushdown(rt);
    if(ql <= mid)
        ret = (ret + query(ql,qr,rt << 1)) % p;
    if(qr > mid)
        ret = (ret + query(ql,qr,rt << 1 | 1)) % p;
    return ret;
}
int Xupdate(int x,int y,int k)
{
    k %= p;
    while(top[x] != top[y])
    {
        if(depth[top[x]] < depth[top[y]]) swap(x,y);
        update(dfn[top[x]],dfn[x],k,1);
        x = fath[top[x]];
    }
    if(depth[x] > depth[y]) swap(x,y);
    update(dfn[x],dfn[y],k,1);
}
int Xquery(int x,int y)
{
    int ret = 0;
    while(top[x] != top[y])
    {
        if(depth[top[x]] < depth[top[y]]) swap(x,y);
        ret = (ret + query(dfn[top[x]],dfn[x],1)) % p;
        x = fath[top[x]];
    }
    if(depth[x] > depth[y]) swap(x,y);
    return ((ret + query(dfn[x],dfn[y],1)) % p);
}

signed main()
{
    n = read(),m = read(),root = read(),p = read();
    for(int i = 1;i <= n;i ++) arr[i] = read();
    for(int i = 1;i < n;i ++)
    {
        int u,v;
        u = read(),v = read();
        tree[u].push_back(v);
        tree[v].push_back(u);
    }
    depth[0] = 1;
    dfs1(root,0);
    dfs2(root,root);
    build(1,n,1);
    for(int i = 1;i <= m;i ++)
    {
        int opt,x,y,z;
        opt = read();
        if(opt == 1)
        {
            x = read(),y = read(),z = read();
            Xupdate(x,y,z);
        }
        if(opt == 2)
        {
            x = read(),y = read();
            printf("%d\n",Xquery(x,y) % p);
        }
        if(opt == 3)
        {
            x = read(),z = read();
            update(dfn[x],dfn[x] + siz[x] - 1,z,1);
        }
        if(opt == 4)
        {
            x = read();
            printf("%d\n",query(dfn[x],dfn[x] + siz[x] - 1,1) % p);
        }
    }
    return 0;
}

by _Kamisato_Ayaka_ @ 2024-11-25 14:56:07

已 AC,此帖结


by cengzh @ 2024-11-27 18:49:52

大师还在吗,是怎么调的,俺也错了@_KamisatoAyaka


by _Kamisato_Ayaka_ @ 2024-11-27 19:01:15

@cengzh

int Xupdate(int x,int y,int k)
{
    k %= p;
    while(top[x] != top[y])
    {
        if(depth[top[x]] < depth[top[y]]) swap(x,y);
        update(dfn[top[x]],dfn[x],k,1);
        x = fath[top[x]];
    }
    if(depth[x] > depth[y]) swap(x,y);
    update(dfn[x],dfn[y],k,1);
}

这个东西返回值类型应该是 void ,我打错了


by cengzh @ 2024-11-27 19:06:34

呜呜不是这个问题,不过还是thx


|