Luo Gu P2590 [ZJOI2008] statistical problem tree tree chain solutions segment tree split +

Topic links: https://www.luogu.org/problem/P2590
tree template strand split title.
Subdivision process takes seven values to the following:

  • fa[u]: U parent node number;
  • dep[u]: U depth;
  • size[u]: Total number of node in the subtree rooted at u;
  • son[u]: U re son;
  • top[u]: Top node where u heavy chain;
  • seg[u]: U line segment tree location;
  • rev[u]: Seg inverted, that is rev[seg[u]] == u.

Then set the interval segment tree template to achieve the most value, and range, and a single point of update operations.

Codes are as follows:

#include <bits/stdc++.h>
using namespace std;
#define INF (1<<29)
const int maxn = 30030;
int fa[maxn],
    dep[maxn],
    size[maxn],
    son[maxn],
    top[maxn],
    seg[maxn], seg_cnt,
    rev[maxn],
    n, w[maxn], maxv[maxn<<2], sumv[maxn<<2];
vector<int> g[maxn];
void dfs1(int u, int p) {
    size[u] = 1;
    for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
        int v = (*it);
        if (v == p) continue;
        fa[v] = u;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        size[u] += size[v];
        if (size[v] >size[son[u]]) son[u] = v;
    }
}
void dfs2(int u, int tp) {
    seg[u] = ++seg_cnt;
    rev[seg_cnt] = u;
    top[u] = tp;
    if (son[u]) dfs2(son[u], tp);
    for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
        int v = (*it);
        if (v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
void push_up(int rt) {
    sumv[rt] = sumv[rt<<1] +sumv[rt<<1|1];
    maxv[rt] = max(maxv[rt<<1], maxv[rt<<1|1]);
}
void build(int l, int r, int rt) {
    int mid = (l + r) / 2;
    if (l == r) {
        sumv[rt] = maxv[rt] = w[rev[l]];
        return;
    }
    build(lson); build(rson);
    push_up(rt);
}
void update(int p, int v, int l, int r, int rt) {
    if (l == r) {
        sumv[rt] = maxv[rt] = v;
        return;
    }
    int mid = (l + r) / 2;
    if (p <= mid) update(p, v, lson);
    else update(p, v, rson);
    push_up(rt);
}
int query_max(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) return maxv[rt];
    int mid = (l + r) / 2, tmp = -INF;
    if (L <= mid) tmp = max(tmp, query_max(L, R, lson));
    if (R > mid) tmp = max(tmp, query_max(L, R, rson));
    return tmp;
}
int query_sum(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) return sumv[rt];
    int mid = (l + r) / 2, tmp = 0;
    if (L <= mid) tmp += query_sum(L, R, lson);
    if (R > mid) tmp += query_sum(L, R, rson);
    return tmp;
}
int ask_max(int u, int v) {
    int res = -INF;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        res = max(res, query_max(seg[top[u]], seg[u], 1, n, 1));
        u = fa[top[u]];
    }
    if (dep[u] < dep[v]) swap(u, v);
    res = max(res, query_max(seg[v], seg[u], 1, n, 1));
    return res;
}
int ask_sum(int u, int v) {
    int res = 0;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        res += query_sum(seg[top[u]], seg[u], 1, n, 1);
        u = fa[top[u]];
    }
    if (dep[u] < dep[v]) swap(u, v);
    res += query_sum(seg[v], seg[u], 1, n, 1);
    return res;
}
int m;
string s;
int main() {
    cin >> n;
    for (int i = 1; i < n; i ++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for (int i = 1; i <= n; i ++) cin >> w[i];
    dep[1] = fa[1] = 1;
    dfs1(1, -1);
    dfs2(1, 1);
    build(1, n, 1);
    cin >> m;
    while (m --) {
        int u, v;
        cin >> s >> u >> v;
        if (s == "CHANGE") update(seg[u], v, 1, n, 1);
        else if (s == "QMAX") cout << ask_max(u, v) << endl;
        else cout << ask_sum(u, v) << endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/codedecision/p/11769437.html