性感树剖在线求调教
查看原帖
性感树剖在线求调教
246331
mystic_qwq楼主2024/8/27 22:56
#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int N = 2e5 + 10;
int n, m, u, v;
string op;
#define rep for (int i = head[u]; i; i = G[i].nex)
struct {
  int to, wt, nex;
} G[N * 2];
int head[N], tot = 1;
void add(int u, int v, int w) {
  G[++tot] = {v, w, head[u]};
  head[u] = tot;
}
int fa[N], d[N], son[N], tp[N], sz[N], dfn[N], nfd[N], cnt, w[N], dir[N];
void dfs1(int u) {
  sz[u] = 1;
  rep {
    int v = G[i].to;
    if (v ^ fa[u])
      fa[v] = u, d[v] = d[u] + 1, dfs1(v), sz[u] += sz[v],
      sz[son[u]] < sz[v] && (son[u] = v);
  }
}
void dfs2(int u, int top) {
  printf("dfs2 %d %d\n", u, top);
  nfd[dfn[u] = ++cnt] = u;
  if (!son[u])
    return;
  tp[u] = top;
  dfs2(son[u], top);
  rep {
    int v = G[i].to;
    if (v != son[u] && v != fa[u])
      ::w[v] = G[i].wt, dir[i / 2] = v, dfs2(v, v);
  }
}
struct sgttree {
#define ls h * 2
#define rs ls | 1
#define mid (l + r >> 1)
#define lson ls, l, mid
#define rson rs, mid + 1, r
#define Tree int h, int l, int r
#define sum(x) t[x].sum
#define rev(x) t[x].rev
#define mx(x) t[x].mx
#define mn(x) t[x].mn
  struct node {
    int sum, rev, mx, mn;
    node operator+(node a) {
      return {sum + a.sum, 0, max(mx, a.mx), min(mn, a.mn)};
    }
  } t[N << 2];
  void pushup(int h) {
    sum(h) = sum(ls) + sum(rs);
    mx(h) = max(mx(ls), mx(rs));
    mn(h) = min(mn(ls), mn(rs));
  }
  void pushdown(int h) {
    if (rev(h)) {
      rev(ls) ^= 1, rev(rs) ^= 1;
      sum(ls) = -sum(ls);
      sum(rs) = -sum(rs);
      int tmp = mx(ls);
      mx(ls) = -mn(ls);
      mn(ls) = -tmp;
      tmp = mx(rs);
      mx(rs) = -mn(rs);
      mn(rs) = -tmp;
      rev(h) = 0;
    }
  }
  void build(Tree) {
    if (l == r) {
      sum(h) = mx(h) = mn(h) = w[nfd[l]];
      return;
    }
    build(lson);
    build(rson);
    pushup(h);
  }
  void modify(Tree, int x, int y) {
    if (l == r) {
      sum(h) = mx(h) = mn(h) = y;
      rev(h) = 0;
      return;
    }
    pushdown(h);
    if (x <= mid)
      modify(lson, x, y);
    else
      modify(rson, x, y);
    pushup(h);
  }
  void update(Tree, int x, int y) {
    printf("update %d %d\n", l, r);
    if (x <= l && r <= y) {
      sum(h) = -sum(h);
      int tmp = mx(h);
      mx(h) = -mn(h);
      mn(h) = -tmp;
      rev(h) ^= 1;
      return;
    }
    pushdown(h);
    if (x <= mid)
      update(lson, x, y);
    if (y > mid)
      update(rson, x, y);
    pushup(h);
  }
  node query(Tree, int x, int y) {
    if (x <= l && r <= y)
      return t[h];
    pushdown(h);
    if (y <= mid)
      return query(lson, x, y);
    if (x > mid)
      return query(rson, x, y);
    return query(lson, x, y) + query(rson, x, y);
  }
  void updateChain(int u, int v) {
    for (; tp[u] ^ tp[v]; u = fa[tp[u]]) {
      if (d[tp[u]] < d[tp[v]])
        swap(u, v);
      update(1, 1, n, dfn[tp[u]], dfn[u]);
    }
    if (d[u] < d[v])
      swap(u, v);
    update(1, 1, n, dfn[v] + 1, dfn[u]);
  }
  int queryChain(int u, int v, int op) {
    int ans = op == 3 ? 1001 : 0;
    for (; tp[u] ^ tp[v]; u = fa[tp[u]]) {
      if (d[tp[u]] < d[tp[v]])
        swap(u, v);
      node res = query(1, 1, n, dfn[tp[u]], dfn[u]);
      if (op == 1)
        ans += res.sum;
      else if (op == 2)
        ans = max(ans, res.mx);
      else if (op == 3)
        ans = min(ans, res.mn);
    }
    if (d[u] < d[v])
      swap(u, v);
    node res = query(1, 1, n, dfn[v] + 1, dfn[u]);
    if (op == 1)
      ans += res.sum;
    else if (op == 2)
      ans = max(ans, res.mx);
    else if (op == 3)
      ans = min(ans, res.mn);
    return ans;
  }
} sgt;
main() {
  // cin.tie(0)->sync_with_stdio(0);
  cin >> n;
  for (int u, v, w, i = 1; i < n; ++i) {
    cin >> u >> v >> w;
    ++u, ++v;
    add(u, v, w);
    add(v, u, w);
  }
  dfs1(1), dfs2(1, 1);
  cout << "w[i]=";
  for (int i = 1; i <= n; ++i)
    cout << w[i] << " \n"[i == n];
  cout << "dir[i]=";
  for (int i = 1; i <= n; ++i)
    cout << dir[i] << " \n"[i == n];
  cout << "dfn[i]=";
  for (int i = 1; i <= n; ++i)
    cout << dfn[i] << " \n"[i == n];
  cout << "nfd[i]=";
  for (int i = 1; i <= n; ++i)
    cout << nfd[i] << " \n"[i == n];
  sgt.build(1, 1, n);
  for (cin >> m; m--;) {
    cin >> op >> u >> v;
    if (op[0] == 'C')
      sgt.modify(1, 1, n, dfn[dir[u]], v);
    else {
      if (u == v)
        continue;
      ++u, ++v;
      if (op[0] == 'N')
        sgt.updateChain(u, v);
      else {
        int op1 = op[0] == 'S' ? 1 : op[1] == 'A' ? 2 : 3;
        cout << sgt.queryChain(u, v, op1) << '\n';
      }
    }
  }
}
2024/8/27 22:56
加载中...