社区讨论

灵异事件!!!

P3178[HAOI2015] 树上操作参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo39ohv8
此快照首次捕获于
2023/10/24 03:04
2 年前
此快照最后确认于
2023/11/25 14:56
2 年前
查看原帖
样例过了,一交全WA 怎么调都调不过
第一个测试点自测会RE (调试显示测试点输入的数少了,不到1000)细思极恐
CPP
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define int long long

constexpr int N = 1e5 + 10;

int n, m, cnt, a_[N], a[N], fa[N], top[N], id[N], sze[N], son[N], dep[N], tr[N << 2], tag[N << 2];
vector <int> g[N];

inline void dfs_1 (int u, int fa_, int dep_)
{
    dep[u] = dep_, fa[u] = fa_, sze[u] = 1;
    for (auto &v : g[u])
        if (v != fa_)
        {
            dfs_1 (v, u, dep_ + 1);
            sze[u] += sze[v], son[u] = (!son[u] ? v : (sze[son[u]] >= sze[v] ? son[u] : v));
        }
}

inline void dfs_2 (int u, int top_)
{
    id[u] = ++cnt, a[cnt] = a_[u], top[u] = top_;
    if (!son[u]) return ;
    dfs_2 (son[u], top_);
    for (auto &v : g[u])
        if (v != fa[u] && v != son[u]) dfs_2 (v, v);
}

inline void build (int x = 1, int l = 1, int r = n)
{
    if (l == r) tr[x] = a[l];
    else
    {
        int mid = l + r >> 1;
        build (x << 1, l, mid), build (x << 1 | 1, mid + 1, r);
        tr[x] = tr[x << 1] + tr[x << 1 | 1];
    }
}

inline void push_down (int x, int l, int r, int mid)
{
    tr[x << 1] += tag[x] * (r - mid + 1), tr[x << 1 | 1] += tag[x] * (mid - l);
    tag[x << 1] += tag[x], tag[x << 1 | 1] += tag[x], tag[x] = 0;
}

inline void update (int l, int r, int d, int x = 1, int nl = 1, int nr = n)
{
    if (l > nr || r < nl) return ;
    if (l <= nl && r >= nr) tag[x] += d, tr[x] += d * (nr - nl + 1);
    else
    {
        int mid = nl + nr >> 1;
        push_down (x, nl, nr, mid);
        update (l, r, d, x << 1, nl, mid), update (l, r, d, x << 1 | 1, mid + 1, nr);
        tr[x] = tr[x << 1] + tr[x << 1 | 1];
    }
}

inline int query (int l, int r, int x = 1, int nl = 1, int nr = n)
{
    if (l > nr || r < nl) return 0;
    if (l <= nl && r >= nr) return tr[x];
    else
    {
        int mid = nl + nr >> 1;
        push_down (x, nl, nr, mid);
        return query (l, r, x << 1, nl, mid) + query (l, r, x << 1 | 1, mid + 1, nr);
    }
}

inline int query_range (int x, int y)
{
    int res = 0;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]]) x ^= y ^= x ^= y;
        res += query (id[top[x]], id[x]), x = fa[top[x]];
    }
    if (dep[x] > dep[y]) x ^= y ^= x ^= y;
    return res += query (id[x], id[y]);
}

namespace FAST_IO_II
{
    inline void write (char ch) { putchar (ch); }
    inline void write (char s[]) { while (*s) putchar (*s++); }
    template <class T> inline void read (T &x) { x = 0; int sgn = false; char c = getchar (); while (c < '0' || c > '9') sgn |= c == '-', c = getchar (); while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar (); x = sgn ? ~x + 1 : x; }
    template <class T> inline void write (T x) { static char c[20]; unsigned p = 0; if (x < 0) putchar ('-'), x = ~x + 1; do c[++p] = x % 10 ^ 48, x /= 10; while (x); while (p) putchar (c[p]), --p; }
    template <class T, class... U> inline void read (T &x, U &...t) { read (x), read (t...); }
    template <class T, class... U> inline void write (T x, U ...t) { write (x), write (t...); }
};
using namespace FAST_IO_II;

signed main ()
{
    read (n, m);
    for (int i = 1; i <= n; ++i) read (a_[i]);
    for (int i = 1, u, v; i < n; ++i) read (u, v), g[u].push_back (v), g[v].push_back (u);

	dfs_1 (1, 1, 1), dfs_2 (1, 1), build ();
	while (m--)
    {
        int opt, x, y; read (opt);
        if (opt == 1) read (x, y), update (id[x], id[x], y);
        if (opt == 2) read (x, y), update (id[x], id[x] + sze[x] - 1, y);
        if (opt == 3) read (x), write (query_range (1, x), '\n');
    }
    return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...