蒟蒻求助
查看原帖
蒟蒻求助
115003
te5555楼主2020/9/4 13:00

树剖调不出来

#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
    int res = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        res = res * 10 + ch - 48, ch = getchar();
    return res * f;
}
const int maxn = 900001;
int head[maxn], cnt;
int dep[maxn], siz[maxn], f[maxn], top[maxn];
int n, m, son[maxn], id[maxn], rk[maxn];
struct edge
{
    int to, nxt;
} e[maxn << 1];
int val[maxn];
inline void add(int from, int to)
{
    e[++cnt].to = to;
    e[cnt].nxt = head[from];
    head[from] = cnt;
}
struct node
{
    int l, r, sum, tag;
#define sum(x) a[x].sum
#define tag(x) a[x].tag
} a[maxn];
#define ls p << 1
#define rs p << 1 | 1
inline void pushup(int p)
{
    sum(p) = sum(ls) + sum(rs);
}
inline void dfs1(int u, int fa)
{
    siz[u] = 1;
    dep[u] = dep[fa] + 1;
    for (register int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if (v == fa)
            continue;
        f[v] = u;
        dfs1(v, u);
        siz[u] += siz[v];
        if (siz[son[u]] < siz[v])
            son[u] = v;
    }
    return;
}
inline void dfs2(int u, int tp)
{
    top[u] = tp;
    id[u] = ++cnt;
    rk[cnt] = u;
    if (!son[u])
        return;
    dfs2(son[u], tp);
    for (register int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if (v != son[u] && v != f[u])
        {
            dfs2(v, v);
        }
    }
}
inline void build(int p, int l, int r)
{
	a[p].l=l;
	a[p].r=r;
    if (l == r)
    {
        sum(p) = val[rk[l]];
        return;
    }
    int mid = l + r >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    a[p].l = a[ls].l;
    a[p].r = a[rs].r;
    pushup(p);
}
inline int get_len(int p)
{
    return a[p].r - a[p].l + 1;
}
inline void pushdown(int p, int l, int r)
{
    if (tag(p))
    {
        int mid = l + r >> 1;
        a[ls].tag += a[p].tag;
        a[rs].tag += a[p].tag;
        sum(ls) += tag(p) * get_len(ls);
        sum(rs) += tag(p) * get_len(rs);
        tag(p) = 0;
    }
}
inline void update(int p, int l, int r, int L, int R, int k)
{
    if (L <= l && R >= r)
    {
        sum(p) += k * get_len(p);
        tag(p) += k;
        return;
    }
    pushdown(p, l, r);
    int mid = l + r >> 1;
    if (L <= mid)
        update(ls, l, mid, L, R, k);
    if (R > mid)
        update(rs, mid + 1, r, L, R, k);
    pushup(p);
    return;
}
inline int query(int p, int l, int r, int L, int R)
{
    if (L <= l && R >= r)
    {
        return sum(p);
    }
    pushdown(p, l, r);
    int mid = l + r >> 1;
    int ans = 0;
    if (L <= mid)
        ans += query(ls, l, mid, L, R);
    if (R > mid)
        ans += query(rs, mid + 1, r, L, R);
    return ans;
}
inline int query_tree(int x, int y)
{
    int res = 0;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        res += query(1, 1, n, id[top[x]], id[x]);
        x = f[top[x]];
    }
    if (id[x] > id[y])
        swap(x, y);
    if (x != y)
        res += query(1, 1, n, id[x], id[y]);
    return res;
}
signed main()
{

    n = read();
    m = read();
    for (register int i = 1; i <= n; i++)
        val[i] = read();
    for (register int x, y, i = 1; i < n; i++)
    {
        x = read();
        y = read();
        add(x, y);
        add(y, x);
    }
    cnt = 0;
    dfs1(1, 0);
    dfs2(1, 1);
    build(1, 1, n);
    while (m--)
    {
        int opt = read();
        int x = read();
        if (opt == 1)
        {
            int y = read();
            update(1, 1, n, id[x], id[x], y);
        }
        else if (opt == 2)
        {
            int y = read();
            update(1, 1, n, id[x], id[x] + siz[x] - 1, y);
        }
        else if (opt == 3)
        {
            cout << query_tree(1, x) << endl;
        }
    }
    return 0;
}
2020/9/4 13:00
加载中...