Only AC on #12 求调,悬关
查看原帖
Only AC on #12 求调,悬关
755759
zhujiangyuan楼主2024/9/24 22:05

调了 2h 了。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
typedef tuple <int, int, int> t3i;
#define MT make_tuple
const int N = 1e6 + 10;
int n, m;
struct Edge { int u, v, w; } e[N];
vector <pii> G[N];
int siz[N], fa[N], a[N], son[N], dfn[N], top[N], dep[N];
namespace Seg {
    int tag[N << 2], sum[N << 2], mav[N << 2], miv[N << 2];
    #define ls p << 1
    #define rs p << 1 | 1
    #define mid ((l + r) >> 1)
    void upd (int p) {
        sum[p] = sum[ls] + sum[rs];
        mav[p] = max (mav[ls], mav[rs]);
        miv[p] = min (miv[ls], miv[rs]);
    }
    void build (int p, int l, int r) {
        if (l == r) return sum[p] = mav[p] = miv[p] = a[l], void (0);
        build (ls, l, mid); build (rs, mid + 1, r);
        upd (p);
    }
    void Set (int p) {
        sum[p] *= -1; int x = miv[p], y = mav[p];
        mav[p] = -x, miv[p] = -y; tag[p] ^= 1;
    }
    void push_down (int p) {
        if (tag[p]) Set (ls), Set (rs), tag[p] = 0;
    }
    void modify1 (int p, int l, int r, int pos, int val) {
        if (l == r) return sum[p] = mav[p] = miv[p] = val, void (0);
        push_down (p);
        if (pos <= mid) modify1 (ls, l, mid, pos, val);
        else modify1 (rs, mid + 1, r, pos, val);
        upd (p);
    }
    void modify2 (int p, int l, int r, int L, int R) {
        if (L <= l && r <= R) return Set (p), void (0);
        push_down (p);
        if (L <= mid) modify2 (ls, l, mid, L, R);
        if (R > mid) modify2 (rs, mid + 1, r, L, R);
        upd (p);
    }
    t3i merge (t3i x, t3i y) {
        return {get <0> (x) + get <0> (y),
            max (get <1> (x), get <1> (y)),
            min (get <2> (x), get <2> (y)) };
    }
    t3i query (int p, int l, int r, int L, int R) {
        if (L <= l && r <= R) return {sum[p], mav[p], miv[p]};
        t3i S = {0, -1001, 1001};
        push_down (p);
        if (L <= mid) S = merge (S, query (ls, l, mid, L, R));
        if (R > mid) S = merge (S, query (rs, mid + 1, r, L, R));
        return S;
    }
}
void dfs1 (int u, int FA) {
    siz[u] = 1; fa[u] = FA; dep[u] = dep[FA] + 1; 
    for (auto [v, w] : G[u]) {
        if (v == FA) continue;
        a[v] = w; dfs1 (v, u);
        siz[u] += siz[v];
        if (siz[v] > siz[son[u]]) son[u] = v;
    }
}
int tot = 0;
void dfs2 (int u, int tp) {
    top[u] = tp; dfn[u] = ++tot;
    if (son[u]) dfs2 (son[u], tp);
    for (auto [v, w] : G[u])
        if (v != fa[u] && v != son[u]) dfs2 (v, v);
}
void Opt1 (int id, int val) {
    int u = e[id].u, v = e[id].v;
    if (v == fa[u]) swap (u, v);
    Seg::modify1 (1, 1, n, dfn[v], val);
}
void Opt2 (int u, int v) {
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap (u, v);
        Seg::modify2 (1, 1, n, dfn[top[u]], dfn[u]);
        u = fa[top[u]];
    }
    if (dep[u] > dep[v]) swap (u, v);
    Seg::modify2 (1, 1, n, dfn[u] + 1, dfn[v]);
}
t3i ask (int u, int v) {
    t3i res = {0, -1001, 1001};
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap (u, v);
        res = Seg::merge (res, Seg::query (1, 1, n, dfn[top[u]], dfn[u]));
        u = fa[top[u]];
    }
    if (dep[u] > dep[v]) swap (u, v);
    res = Seg::merge (res, Seg::query (1, 1, n, dfn[u] + 1, dfn[v]));
    return res;
}
signed main () {
#ifdef ZJY
    freopen ("in.cpp", "r", stdin);
    freopen ("out.cpp", "w", stdout);
#endif
    ios::sync_with_stdio (false);
    cin.tie (0); cout.tie (0);
    
    cin >> n;
    for (int i = 1, u, v, w; i < n; i++) {
        cin >> u >> v >> w; u++, v++;
        G[u].push_back ({v, w});
        G[v].push_back ({u, w});
        e[i] = {u, v, w};
    }
    dfs1 (1, 0); dfs2 (1, 1);
    Seg::build (1, 1, n);
    cin >> m;
    string opt; int u, v;
    while (m--) {
        cin >> opt >> u >> v; u++, v++;
        if (opt == "C") u--, v--, Opt1 (u, v);
        else if (opt == "N") Opt2 (u, v);
        else if (opt == "SUM") cout << (get <0> (ask (u, v))) << '\n';
        else if (opt == "MAX") cout << (get <1> (ask (u, v))) << '\n';
        else cout << (get <2> (ask (u, v))) << '\n';
    }
    return 0;
}
2024/9/24 22:05
加载中...