树剖WA求调
查看原帖
树剖WA求调
546558
Land_ER楼主2022/4/7 15:26
#include<bits/stdc++.h>
int n,m,r,p;
std::vector<int> g[100005];
int w[100005];
void input(void){
    int x,y;
    scanf("%d%d%d%d",&n,&m,&r,&p);
    for(int i = 1;i <= n;++ i)
        scanf("%d",w+i);
    for(int i = 1;i <= n-1;++ i){
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    return;
}
int siz[100005],dep[100005],fa[100005],son[100005];
void dfs1(int id,int f){
    dep[id] = dep[f] + 1;
    fa[id] = f;
    siz[id] = 1;
    for(auto v : g[id]){
        if(v == f)
            continue;
        dfs1(v,id);
        siz[id] += siz[v];
        son[id] = siz[v]>siz[son[id]] ? v : son[id];
    }
    return;
}
int a[100005],dfn[100005],top[100005],tot = 1;
void dfs2(int id,int t){
    a[tot] = w[id];
    dfn[id] = tot;
    ++ tot;
    top[id] = t;
    if(!son[id])
        return;
    dfs2(son[id],t);
    for(auto v : g[id]){
        if(dfn[v])
            continue;
        dfs2(v,v);
    }
    return;
}
int d[100005*4],t[100005*4];
#define mid ((l+r)>>1)
#define lc (id<<1)
#define rc (id<<1|1)
void build(int id,int l,int r){
    if(l == r)
        d[id] = a[l];
    else{
        build(lc,l,mid);
        build(rc,mid+1,r);
        d[id] = (d[lc] + d[rc]) % p;
    }
    return;
}
void pushdown(int id,int l,int r){
    d[lc] = (d[lc] + (mid - l + 1) * t[id] % p) % p;
    d[rc] = (d[rc] + (r - mid) * t[id] % p) % p;
    t[lc] = (t[lc] + t[id]) % p;
    t[rc] = (t[rc] + t[id]) % p;
    t[id] = 0;
    return;
}
void modify(int id,int l,int r,int s,int e,int c){
    if(l == r)
        d[id] += c;
    else{
        if(s <= l && e >= r){
            d[id] = (d[id] + c * (r - l + 1) % p) % p;
            t[id] = (t[id] + c) % p;
        }else{
            pushdown(id,l,r);
            if(s <= mid)
                modify(lc,l,mid,s,e,c);
            if(e > mid)
                modify(rc,mid+1,r,s,e,c);
            d[id] = (d[lc] + d[rc]) % p;
        }
    }
    return;
}
int query(int id,int l,int r,int s,int e){
    if(l == r)
        return d[id];
    if(s <= l && e >= r)
        return d[id];
    pushdown(id,l,r);
    int ans = 0;
    if(s <= mid)
        ans = (ans + query(lc,l,mid,s,e)) % p;
    if(e > mid)
        ans = (ans + query(rc,mid+1,r,s,e)) % p;
    return ans;
}
#undef mid
#undef lc
#undef rc
using std::swap;
void modify1(int x,int y,int z){
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]])
            swap(x,y);
        modify(1,1,n,dfn[top[x]],dfn[x],z);
        x = fa[top[x]];
    }
    if(dep[x] < dep[y])
        swap(x,y);
    modify(1,1,n,dfn[y],dfn[x],z);
    return;
}
int query1(int x,int y){
    int ans = 0;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]])
            swap(x,y);
        ans = (ans + query(1,1,n,dfn[top[x]],dfn[x])) % p;
        x = fa[top[x]];
    }
    if(dep[x] < dep[y])
        swap(x,y);
    ans = (ans + query(1,1,n,dfn[y],dfn[x])) % p;
    return ans;
}
void modify2(int x,int z){
    modify(1,1,n,dfn[x],dfn[x]+siz[x]-1,z);
    return;
}
int query2(int x){
    return query(1,1,n,dfn[x],dfn[x+siz[x]-1]);
}
int main(void){
    int op,x,y,z;
    input();
    dfs1(r,0);
    dfs2(r,r);
    build(1,1,n);
    while(m --){
        scanf("%d%d",&op,&x);
        switch(op){
            case 1:
                scanf("%d%d",&y,&z);
                modify1(x,y,z%p);
                break;
            case 2:
                scanf("%d",&y);
                printf("%d\n",query1(x,y));
                break;
            case 3:
                scanf("%d",&z);
                modify2(x,z%p);
                break;
            case 4:
                printf("%d\n",query2(x));
        }
    }
    return 0;
}
2022/4/7 15:26
加载中...