非递归线段树求调
查看原帖
非递归线段树求调
207996
yzy1Ẽd<ßDream楼主2022/1/6 18:06

RT,这份代码中的线段树部分(即 Seg 结构体)有问题,换成正常的线段树可 AC。

打算用这题来练习非递归线段树的,现在找不到 bug 在哪,求调。

其中 Cha 为单点修改,Fil 为区间推平,Add 为区间加。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double lf;

#define int ll
#define rep(i, f, t) for (int i = (f), ed##i = (t); i <= ed##i; ++i)
#define re(i, t) rep (i, 1, t)
#define per(i, t, f) for (int i = (t), ed##i = (f); i >= ed##i; --i)
#define ste(i, f, t, s) for (int i = (f), ed##i = (t); i <= ed##i; i += s)
#define each(i, x) for (auto &&i : (x))
#define nxt(i, f, g) for (int i = g.h[f]; i; i = g.e[i].n)
#define dbg(x) (cerr << "(dbg) " << #x " = " << (x) << '\n')
#define umod(x) ((x) >= mo && ((x) -= mo))
#define dmod(x) ((x) < 0 && ((x) += mo))
#define up(x, y) (((x) < (y)) && ((x) = (y)))
#define down(x, y) (((x) > (y)) && ((x) = (y)))
#define y1 y1__
#define fio(x) (freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout))

const int N = 2e5 + 9;

struct G {
  int h[N], tot;
  struct E {
    int t, n, v;
  } e[N];
  void Add(int f, int t, int v) { e[++tot] = {t, h[f], v}, h[f] = tot; }
} g;

int n, tim, dfn[N], son[N], sz[N], fa[N], dep[N], a[N], tp[N];

struct Seg {
  struct T {
    int add, fil, mx;
    void Fil(int x) { fil = x, add = 0, mx = x; }
    void Add(int x) { add += x, mx += x; }
  } d[N << 2];
  int M, T;

  void Down(int u) {
    per (i, T, 1) {
      int v = u >> i;
      if (d[v].fil) d[v << 1].Fil(d[v].fil), d[v << 1 | 1].Fil(d[v].fil), d[v].fil = 0;
      if (d[v].add) d[v << 1].Add(d[v].add), d[v << 1 | 1].Add(d[v].add), d[v].add = 0;
    }
  }

  void Up(int u) {
    while (u > 1) u >>= 1, d[u].mx = max(d[u << 1].mx, d[u << 1 | 1].mx);
  }

  void Build() {
    for (T = 1, M = 1; M <= n; M <<= 1) ++T;
    rep (i, M + 1, M + n)
      d[i].mx = a[i - M];
    per (i, M - 1, 1)
      d[i].mx = max(d[i << 1].mx, d[i << 1 | 1].mx);
  }

  void Cha(int u, int x) { u += M, Down(u), d[u].mx = x, Up(u); }

  void Add(int l, int r, int x) {
    l += M, r += M;
    int l0 = l, r0 = r;
    for (--l, ++r; l ^ r ^ 1; l >>= 1, r >>= 1) {
      if (~l & 1) d[l ^ 1].Add(x);
      if (r & 1) d[r ^ 1].Add(x);
    }
    Down(l0), Down(r0);
    Up(l0), Up(r0);
  }

  void Fil(int l, int r, int x) {
    l += M, r += M;
    int l0 = l, r0 = r;
    for (--l, ++r; l ^ r ^ 1; l >>= 1, r >>= 1) {
      if (~l & 1) d[l ^ 1].Fil(x);
      if (r & 1) d[r ^ 1].Fil(x);
    }
    Down(l0), Down(r0);
    Up(l0), Up(r0);
  }

  int Ask(int l, int r) {
    l += M, r += M;
    Down(l), Down(r);
    ll ans = 0;
    for (--l, ++r; l ^ r ^ 1; l >>= 1, r >>= 1) {
      if (~l & 1) up(ans, d[l ^ 1].mx);
      if (r & 1) up(ans, d[r ^ 1].mx);
    }
    return ans;
  }
} seg;

void Dfs1(int f) {
  dep[f] = dep[fa[f]] + 1;
  // dbg(f);
  sz[f] = 1;
  nxt (i, f, g) {
    int t = g.e[i].t;
    if (t == fa[f]) continue;
    fa[t] = f, Dfs1(t), sz[f] += sz[t];
    if (sz[t] > sz[son[f]]) son[f] = t;
  }
}

void Dfs2(int f) {
  dfn[f] = ++tim;
  // dbg(f);
  if (!son[f]) return;
  nxt (i, f, g) {
    int t = g.e[i].t;
    if (t == fa[f]) continue;
    if (t != son[f]) continue;
    tp[t] = tp[f], Dfs2(t), a[dfn[t]] = g.e[i].v;
  }
  nxt (i, f, g) {
    int t = g.e[i].t;
    if (t == fa[f]) continue;
    if (t == son[f]) continue;
    tp[t] = t, Dfs2(t), a[dfn[t]] = g.e[i].v;
  }
}

char op[10];

void Cha(int x, int y) { seg.Cha(max(dfn[g.e[x * 2 - 1].t], dfn[g.e[x * 2].t]), y); }

void Add(int f, int t, int x) {
  while (tp[f] != tp[t]) {
    if (dep[tp[f]] > dep[tp[t]]) swap(f, t);
    seg.Add(dfn[tp[t]], dfn[t], x);
    t = fa[tp[t]];
  }
  if (dfn[f] > dfn[t]) swap(f, t);
  if (f != t) seg.Add(dfn[f] + 1, dfn[t], x);
}

void Fil(int f, int t, int x) {
  while (tp[f] != tp[t]) {
    if (dep[tp[f]] > dep[tp[t]]) swap(f, t);
    seg.Fil(dfn[tp[t]], dfn[t], x);
    t = fa[tp[t]];
  }
  if (dfn[f] > dfn[t]) swap(f, t);
  if (f != t) seg.Fil(dfn[f] + 1, dfn[t], x);
}

int Ask(int f, int t) {
  int ans = 0;
  while (tp[f] != tp[t]) {
    if (dep[tp[f]] > dep[tp[t]]) swap(f, t);
    // cerr << dfn[tp[t]] << ' ' << dfn[t] << ' ' << seg.Ask(dfn[tp[t]], dfn[t]) << '\n';
    up(ans, seg.Ask(dfn[tp[t]], dfn[t]));
    // dbg(ans);
    t = fa[tp[t]];
  }
  if (dfn[f] > dfn[t]) swap(f, t);
  // dbg(f);
  // dbg(t);
  // cerr << dfn[f] + 1 << ' ' << dfn[t] << ' ' << seg.Ask(dfn[f] + 1, dfn[t]) << '\n';
  if (f != t) up(ans, seg.Ask(dfn[f] + 1, dfn[t]));
  // cerr << "----------" << '\n';
  return ans;
}

signed main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n;
  re (i, n - 1) {
    int f, t, v;
    cin >> f >> t >> v;
    g.Add(f, t, v), g.Add(t, f, v);
  }
  Dfs1(1);
  tp[1] = 1, Dfs2(1);
  // re (i, n)
  //   cerr << a[i] << ' ';
  // cerr << '\n';
  seg.Build();
  while (1) {
    cin >> op;
    if (*op == 'S')
      break;
    else if (op[1] == 'h') {
      int x, y;
      cin >> x >> y;
      Cha(x, y);
    } else if (op[1] == 'o') {
      int x, y, z;
      cin >> x >> y >> z;
      Fil(x, y, z);
    } else if (op[1] == 'd') {
      int x, y, z;
      cin >> x >> y >> z;
      Add(x, y, z);
    } else {
      int x, y;
      cin >> x >> y;
      int res = Ask(x, y);
      cout << res << '\n';
    }
    // re (i, seg.M + n)
    //   cerr << i << ' ' << seg.d[i].fil << ' ' << seg.d[i].add << ' ' << seg.d[i].mx << '\n';
    // cerr << "==========\n";
  }
  return 0;
}
2022/1/6 18:06
加载中...