20pts AC#5#6,码风良好,求调,玄关。
查看原帖
20pts AC#5#6,码风良好,求调,玄关。
342185
__builtin_orz楼主2024/8/2 11:09
#include <limits.h>
#include <stdio.h>
#include <string.h>
#define int long long
#define each(i, x) for (int i = x[head]; i; i = i[nxt])
#define SLC(x) (x * 2)
#define SRC(x) (x * 2 + 1)
#define N size_t(3e5 + 4)
int n, q;
int head[N], to[2 * N], nxt[2 * N], mtp;
int siz[N], son[N], fa[N], dep[N], top[N];
int dfn[N], rnk[N], cnt;
int segMax[4 * N], segSum[4 * N];
int max(int x, int y) { return x > y ? x : y; }
void swap(int& x, int& y) {
  int z = y;
  y = x;
  x = z;
}
void CFS_add_edge_1(int f, int t) {
  mtp++;
  mtp[to] = t;
  mtp[nxt] = f[head];
  f[head] = mtp;
}
void CFS_add_edge_2(int f, int t) {
  CFS_add_edge_1(f, t);
  CFS_add_edge_1(t, f);
}
void HLD_build_1(int now, int last) {
  now[siz] = 1;
  each(i, now) {
    if (i[to] != last) {
      i[to][dep] = now[dep] + 1;
      i[to][fa] = now;
      HLD_build_1(i[to], now);
      now[siz] += i[to][siz];
      if (i[to][siz] > now[son][siz]) now[son] = i[to];
    }
  }
}
void HLD_build_2(int now, int tp) {
  cnt++;
  dfn[now] = cnt;
  rnk[cnt] = now;
  now[top] = tp;
  if (now[son]) HLD_build_2(now[son], tp);
  each(i, now) {
    if (i[to] != now[fa] && i[to] != now[son]) HLD_build_2(i[to], i[to]);
  }
}
void Seg_pushup(int now) {
  now[segSum] = SLC(now)[segSum] + SRC(now)[segSum];
  now[segMax] = max(SLC(now)[segMax], SRC(now)[segMax]);
}
void Seg_build(int now, int nl, int nr) {
  int nm = (nl + nr) / 2;
  if (nl == nr) {
    scanf("%lld", now + segSum);
    now[segMax] = now[segSum];
  } else {
    Seg_build(SLC(now), nl, nm);
    Seg_build(SRC(now), nm + 1, nr);
    Seg_pushup(now);
  }
}
void Seg_update(int now, int nl, int nr, int cid, int cval) {
  if (nl == nr)
    now[segSum] = now[segMax] = cval;
  else {
    int nm = (nl + nr) / 2;
    if (cid <= nm)
      Seg_update(SLC(now), nl, nm, cid, cval);
    else
      Seg_update(SRC(now), nm + 1, nr, cid, cval);
    Seg_pushup(now);
  }
}
int Seg_query_sum(int now, int nl, int nr, int ql, int qr) {
  if (ql <= nl && nr <= qr) return now[segSum];
  int nm = (nl + nr) / 2, ret = 0;
  if (ql <= nm) ret += Seg_query_sum(SLC(now), nl, nm, ql, qr);
  if (nm + 1 <= qr) ret += Seg_query_sum(SRC(now), nm + 1, nr, ql, qr);
  return ret;
}
int Seg_query_max(int now, int nl, int nr, int ql, int qr) {
  if (ql <= nl && nr <= qr) return now[segMax];
  int nm = (nl + nr) / 2, ret = INT_MIN;
  if (ql <= nm) ret = max(ret, Seg_query_max(SLC(now), nl, nm, ql, qr));
  if (nm + 1 <= qr) ret = max(ret, Seg_query_max(SRC(now), nm + 1, nr, ql, qr));
  return ret;
}
int HLD_query_sum(int u, int v) {
  int ans = 0;
  while (top[u] != top[v]) {
    if (u[top][dep] < v[top][dep]) swap(u, v);
    ans += Seg_query_sum(1, 1, n, u[top][dfn], u[dfn]);
    u = u[top][fa];
  }
  if (dep[u] < dep[v]) swap(u, v);
  ans += Seg_query_sum(1, 1, n, dfn[v], dfn[u]);
  return ans;
}
int HLD_query_max(int u, int v) {
  int ans = INT_MIN;
  while (top[u] != top[v]) {
    if (u[top][dep] < v[top][dep]) swap(u, v);
    ans = max(ans, Seg_query_max(1, 1, n, u[top][dfn], u[dfn]));
    u = u[top][fa];
  }
  if (dep[u] < dep[v]) swap(u, v);
  ans = max(ans, Seg_query_max(1, 1, n, dfn[v], dfn[u]));
  return ans;
}
signed main() {
  scanf("%lld", &n);
  for (int i = 2; i <= n; i++) {
    int x, y;
    scanf("%lld%lld", &x, &y);
    CFS_add_edge_2(x, y);
  }
  dep[1] = fa[1] = 1;
  HLD_build_1(1, 0);
  HLD_build_2(1, 1);
  Seg_build(1, 1, n);
  scanf("%lld", &q);
  for (int i = 1; i <= q; i++) {
    int x, y;
    char cmd[10];
    scanf("%s%lld%lld", cmd, &x, &y);
    if (!strcmp(cmd, "CHANGE")) Seg_update(1, 1, n, dfn[x], y);
    if (!strcmp(cmd, "QMAX")) printf("%lld\n", HLD_query_max(x, y));
    if (!strcmp(cmd, "QSUM")) printf("%lld\n", HLD_query_sum(x, y));
  }
  return 0;
}
2024/8/2 11:09
加载中...