刚学树剖,30pts其他全wa了

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

@[Tangent233](/user/264548) 说实话真的没有看太懂,有兴趣的话可以看一下我的 ```cpp # include <iostream> # include <cstdio> using namespace std; typedef long long ll; const int N = 1e6 + 5; typedef struct { int x , y , next; }Edge; Edge edge[N]; int E = 0 , elast[N]; void add(int x , int y ) { E ++; edge[E].x = x; edge[E].y = y; edge[E].next = elast[x]; elast[x] = E; } int f[N] , dep[N] , son[N] , siz[N]; void dfs1(int x , int fa) { dep[x] = dep[fa] + 1; f[x] = fa; siz[x] = 1; int maxv = -1; for (int i = elast[x] ; i ; i = edge[i].next) { int y = edge[i].y; if (y != fa) { dfs1(y , x); siz[x] += siz[y]; if (siz[y] > maxv) son[x] = y , maxv = siz[y]; } } } int top[N] , id[N] , w[N] , W[N] , Cnt = 0; int n , m , root , mod; void dfs2(int x , int Top) { id[x] = ++ Cnt; w[Cnt] = W[x]; top[x] = Top; if (!son[x]) return ; dfs2(son[x] , Top); for (int i = elast[x] ; i ; i = edge[i].next) { int y = edge[i].y; if (y != f[x] && y != son[x]) dfs2(y , y); } } typedef struct { int l , r , lazy; ll sum; }Node; Node tr[N]; void pushup(int p) { tr[p].sum = tr[p << 1].sum + tr[p << 1 | 1].sum; tr[p].sum %= mod; } void pushdown(int p) { if (tr[p].lazy) { tr[p << 1].lazy += tr[p].lazy; tr[p << 1 | 1].lazy += tr[p].lazy; tr[p << 1].sum += (ll)(tr[p << 1].r - tr[p << 1].l + 1) * (tr[p].lazy); tr[p << 1 | 1].sum += (ll)(tr[p << 1 | 1].r - tr[p << 1 | 1].l + 1) * (tr[p].lazy); tr[p << 1].sum %= mod; tr[p << 1 | 1].sum %= mod; tr[p].lazy = 0; } return ; } void modify(int p , int x , int y , int d) { if (x > y) swap(x , y); if (x <= tr[p].l && tr[p].r <= y) { tr[p].lazy += d; tr[p].sum = (tr[p].sum + (ll)(tr[p].r - tr[p].l + 1) * d % mod) % mod; return ; } else { pushdown(p); int mid = (tr[p].l + tr[p].r) >> 1; if (x <= mid) modify(p << 1 , x , y , d); if (y > mid) modify(p << 1 | 1 , x , y , d); pushup(p); } } ll query(int p , int x , int y) { if (x > y) swap(x , y); if (x <= tr[p].l && tr[p].r <= y) return tr[p].sum % mod; else { pushdown(p); int mid = (tr[p].l + tr[p].r) >> 1; ll ans = 0; if (x <= mid) ans += query(p << 1 , x , y); if (y > mid) ans += query(p << 1 | 1 , x , y); return ans % mod; } } void build(int p , int x , int y) { tr[p].l = x; tr[p].r = y; if (x == y) { tr[p].sum = (ll)w[x]; return ; } else { int mid = (x + y) >> 1; build(p << 1 , x , mid) , build(p << 1 | 1 , mid + 1 , y); pushup(p); } } ll Query(int x , int y) { ll ans = 0; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x , y); ans = (ans + query(1 , id[top[x]] , id[x])) % mod; x = f[top[x]]; } if (dep[x] > dep[y]) swap(x , y); ans = (ans + query(1 , id[x] , id[y])) % mod; return ans % mod; } void Add(int x , int y , int d) { d %= mod; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x , y); modify(1 , id[top[x]] , id[x] , d); x = f[top[x]]; } if (dep[x] > dep[y]) swap(x , y); modify(1 , id[x] , id[y] , d); } int main() { cin >> n >> m >> root >> mod; for (int i = 1 ; i <= n ; i ++) { scanf("%d" , &W[i]); } for (int i = 1 ; i <= n - 1 ; i ++) { int x , y; scanf("%d%d" , &x , &y); add(x , y) , add(y , x); } dfs1(root , 0); dfs2(root , root); build(1 , 1 , n); while (m --) { int x , y , z , opt; scanf("%d%d" , &opt , &x); if (opt == 1) { scanf("%d%d" , &y , &z); Add(x , y , z); } if (opt == 2) { scanf("%d" , &y); printf("%lld\n" , Query(x , y) % mod); } if (opt == 3) { scanf("%d" , &y); modify(1 , id[x] , id[x] + siz[x] - 1 , y); } if (opt == 4) { printf("%lld\n" , query(1 , id[x] , id[x] + siz[x] - 1) % mod); } } } ```
by ker_xyxyxyx_xxs @ 2021-08-22 14:37:59


@[ker_xyxyxyx_xxs](/user/335477) 主要是因为我是平衡树维护来着( 后面树剖的代码也没看懂吗
by Tangent233 @ 2021-08-22 14:42:13


@[Tangent233](/user/264548) 哦哦哦,那就是了 dfs我感觉没有问题
by ker_xyxyxyx_xxs @ 2021-08-22 14:46:22


@[ker_xyxyxyx_xxs](/user/335477) 平衡树锅了?
by Tangent233 @ 2021-08-22 15:23:05


@[Tangent233](/user/264548) 我不会平衡树,我看起来感觉dfs没问题,也不能保证
by ker_xyxyxyx_xxs @ 2021-08-22 16:15:22


|