树剖20ptsTLE求助
查看原帖
树剖20ptsTLE求助
707461
100kt_WNW楼主2022/5/17 17:15
/*
 * @Author: 100kt_northwest
 * @Date: 2022-05-17 16:02:15
 * @LastEditors: 100kt_northwest
 * @LastEditTime: 2022-05-17 17:14:21
 */
#include <cstdio>
#include <iostream>
#include <memory.h>
#define lc t << 1
#define rc t << 1 | 1
#define ll long long
#define N 30009
using namespace std;
void to_max(ll& a, ll b)
{
    a = (a >= b ? a : b);
}
class SegTree {
private:
    struct Seg {
        int l, r;
        ll sum, mx;
    } tr[N << 2];

public:
    inline void pushup(int t)
    {
        Seg* now = &tr[t];
        Seg *l_c = &tr[lc], *r_c = &tr[rc];
        now->sum = l_c->sum + r_c->sum;
        now->mx = max(l_c->mx, r_c->mx);
    }
    void builder(ll f[], int t, int l, int r)
    {
        Seg* now = &tr[t];
        now->l = l, now->r = r;
        if (l == r) {
            now->mx = f[l];
            now->sum = f[l];
            return;
        }
        int mid = (l + r) >> 1;
        builder(f, lc, l, mid);
        builder(f, rc, mid + 1, r);
        pushup(t);
    }
    void update(int t, int idx, ll val)
    {
        Seg* now = &tr[t];
        if (now->l == now->r) {
            now->mx = val;
            now->sum = val;
            return;
        }
        int mid = (now->l + now->r) >> 1;
        if (idx <= mid)
            update(lc, idx, val);
        if (idx > mid)
            update(rc, idx, val);
        pushup(t);
    }
    ll rsq(int t, int l, int r)
    {
        Seg* now = &tr[t];
        if (l <= now->l && now->r <= r)
            return now->sum;
        int mid = (now->l + now->r) >> 1;
        ll res = 0;
        if (l <= mid)
            res += rsq(lc, l, r);
        if (r > mid)
            res += rsq(rc, l, r);
        return res;
    }
    ll rmq(int t, int l, int r)
    {
        Seg* now = &tr[t];
        if (l <= now->l && now->r <= r)
            return now->mx;
        int mid = (now->l + now->r) >> 1;
        ll res = -1e9;
        if (l <= mid)
            to_max(res, rmq(lc, l, r));
        if (r > mid)
            to_max(res, rmq(rc, l, r));
        return res;
    }
};
SegTree seg_tree;
// SegTree
struct edge {
    int to;
    int nxt;
} E[N << 1];
int hd[N], tt;
void addedge(int u, int v)
{
    E[++tt] = (edge) {v, hd[u]};
    hd[u] = tt;
}
ll arr[N], nodeW[N];
int top[N], tI[N], tO[N], son[N];
int p[N], d[N], sz[N];
int n, m;
void init()
{
    for (int u = 1; u <= n; ++u)
        arr[tI[u]] = nodeW[u];
    seg_tree.builder(arr, 1, 1, n);
}
void dfs_sz(int u, int fa)
{
    p[u] = fa;
    d[u] = d[fa] + 1;
    sz[u] = 1;
    for (int i = hd[u]; i; i = E[i].nxt) {
        int v = E[i].to;
        if (v == fa)
            continue;
        dfs_sz(v, u);
        sz[u] += sz[v];
        if (sz[v] > sz[son[u]] || sz[v] == sz[son[u]] && v < son[u])
            son[u] = v;
    }
}
int timer;
void dfs_top(int u, int fa)
{
    tI[u] = ++timer;
    tO[u] = tI[u] + sz[u] - 1;
    top[u] = (u == son[fa] ? top[fa] : u);
    if (sz[u] == 1)
        return;
    dfs_top(son[u], u);
    for (int i = hd[u]; i; i = E[i].nxt) {
        int v = E[i].to;
        if (v == fa || v == son[u])
            continue;
        dfs_top(v, u);
    }
}
void NodeUpd(int u, ll val)
{
    seg_tree.update(1, tI[u], val);
}
ll LineRmq(int u, int v)
{
    ll res = -1e9;
    while (top[u] != top[v]) {
        if (d[top[u]] > d[top[u]]) {
            to_max(res, seg_tree.rmq(1, tI[top[u]], u));
            u = p[top[u]];
        } else {
            to_max(res, seg_tree.rmq(1, tI[top[v]], v));
            v = p[top[v]];
        }
    }
    if (d[u] > d[v])
        swap(u, v);
    to_max(res, seg_tree.rmq(1, tI[u], tI[v]));
    return res;
}
ll LineRsq(int u, int v)
{
    ll res = 0;
    while (top[u] != top[v]) {
        if (d[top[u]] > d[top[v]]) {
            res += seg_tree.rsq(1, tI[top[u]], u);
            u = p[top[u]];
        } else {
            res += seg_tree.rsq(1, tI[top[v]], v);
            v = p[top[v]];
        }
    }
    if (d[u] > d[v])
        swap(u, v);
    res += seg_tree.rsq(1, tI[u], tI[v]);
    return res;
}
void quick()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main()
{
    quick();
    cin >> n;
    for (int i = 1, u, v; i < n; ++i) {
        cin >> u >> v;
        addedge(u, v);
        addedge(v, u);
    }
    for (int i = 1; i <= n; ++i)
        cin >> nodeW[i];

    dfs_sz(1, 0);
    dfs_top(1, 0);
    init();
    cin >> m;
    while (m--) {
        string op;
        int u, v;
        ll val;
        cin >> op;
        if (op == "CHANGE") {
            cin >> u >> val;
            NodeUpd(u, val);
        } else if (op == "QMAX") {
            cin >> u >> v;
            cout << LineRmq(u, v) << endl;
        } else {
            cin >> u >> v;
            cout << LineRsq(u, v) << endl;
        }
    }
    return 0;
}
2022/5/17 17:15
加载中...