萌新splay求助
查看原帖
萌新splay求助
242973
hly1204楼主2020/5/2 02:29

好像是哪里死循环了。。

因为这题不用堆的操作,所以只是用splay的框架,但是其实不是搜索树,只是存一下值和最大值,然后外层用splay。。内层也是splay,有没有大佬帮忙看看哪里死循环了。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 3e5 + 5;

//------------ small
int ch[N][2], fa[N], val[N], val_max[N], lazy_tag[N]; // small
int g_ch[N][2], g_fa[N], g_val_max[N];                // big

void helper(int x, int v) { x != 0 && (val[x] += v, val_max[x] += v, lazy_tag[x] += v); }
void pushdown(int x) {
  helper(ch[x][0], lazy_tag[x]), helper(ch[x][1], lazy_tag[x]), lazy_tag[x] = 0;
}
void pushup(int x) { val_max[x] = max({val[x], val_max[ch[x][0]], val_max[ch[x][1]]}); }
void rotate(int x) {
  int y = fa[x], d = ch[y][0] == x, z = g_fa[x];
  pushdown(y), pushdown(x);
  fa[ch[y][1 ^ d] = ch[x][d]] = y;
  if (fa[y]) ch[fa[y]][ch[fa[y]][1] == y] = x;
  fa[x] = fa[y], ch[x][d] = y, fa[y] = x;
  if (z) {
    g_fa[x] = g_fa[z], g_ch[g_fa[z]][g_ch[g_fa[z]][1] == z] = x;
    g_ch[x][0] = g_ch[z][0], g_ch[x][1] = g_ch[z][1];
    g_fa[g_ch[x][0]] = g_fa[g_ch[x][1]] = x;
    g_ch[z][0] = g_ch[z][1] = g_fa[z] = 0;
  }
  pushup(y);
}
void splay(int x) {
  if (!x) return;
  for (int y; (y = fa[x]) != 0; rotate(x))
    if (fa[y] != 0) rotate((ch[fa[y]][0] == y ^ ch[y][0] == x) ? x : y);
  pushup(x);
}
//------------ llams
//------------ big
void g_pushup(int x) {
  g_val_max[x] = max({val_max[x], g_val_max[g_ch[x][0]], g_val_max[g_ch[x][1]]});
}
void g_rotate(int x) {
  int y = g_fa[x], d = g_ch[y][0] == x;
  g_fa[g_ch[y][1 ^ d] = g_ch[x][d]] = y;
  if (g_fa[y]) g_ch[g_fa[y]][g_ch[g_fa[y]][1] == y] = x;
  g_fa[x] = g_fa[y], g_ch[x][d] = y, g_fa[y] = x;
  g_pushup(y);
}
void g_splay(int x) {
  if (!x) return;
  for (int y; (y = g_fa[x]) != 0; g_rotate(x))
    if (g_fa[y] != 0) g_rotate((g_ch[g_fa[y]][0] == y ^ g_ch[y][0] == x) ? x : y);
  g_pushup(x);
}
//------------ gib
void create() {
  g_val_max[0] = val[0] = val_max[0] = numeric_limits<int>::min();
  int n;
  cin >> n;
  for (int i = 1; i <= n; ++i) cin >> val[i];
  function<void(int, int, int &, int)> rec = [&rec](int l, int r, int &pos, int f) {
    if (l <= r) {
      g_fa[pos = l + r >> 1] = f;
      val_max[pos] = val[pos];
      rec(l, pos - 1, g_ch[pos][0], pos), rec(pos + 1, r, g_ch[pos][1], pos);
      g_val_max[pos] = max({val[pos], g_val_max[g_ch[pos][0]], g_val_max[g_ch[pos][1]]});
    }
  };
  int root;
  rec(1, n, root, 0);
}
void solve() {
  int q, add_tot = 0;
  cin >> q;
  char cmd[5];
  auto find_fa = [](int x) {
    while (fa[x]) x = fa[x];
    return x;
  };
  auto find_min = [](int x) {
    while (ch[x][0]) x = ch[x][0];
    return x;
  };
  auto g_find_min = [](int x) {
    while (g_ch[x][0]) x = g_ch[x][0];
    return x;
  };
  auto meld_2 = [&](int x, int y) {
    int t = find_min(x);
    splay(t);
    ch[t][0] = y, fa[y] = t;
    pushup(t);
    return t;
  };
  auto g_meld_2 = [&](int x, int y) {
    int t = g_find_min(x);
    g_splay(t);
    g_ch[t][0] = y, g_fa[y] = t;
    g_pushup(t);
    return t;
  };
  while (q--) {
    cin >> cmd;
    if (cmd[0] == 'U') {
      int u, v;
      cin >> u >> v;
      int a = find_fa(u), b = find_fa(v);
      if (a != b) {
        g_splay(a);
        int c = g_ch[a][0], d = g_ch[a][1];
        g_ch[a][0] = g_ch[a][1] = g_fa[c] = g_fa[d] = 0;
        g_meld_2(c, d), g_splay(b);
        c = g_ch[b][0], d = g_ch[b][1];
        g_ch[b][0] = g_ch[b][1] = g_fa[c] = g_fa[d] = 0;
        g_meld_2(meld_2(a, b), g_meld_2(c, d));
      }
    } else if (cmd[0] == 'A') {
      if (cmd[1] == '1') {
        int x, v;
        cin >> x >> v;
        splay(x), g_splay(x);
        val[x] += v;
        pushup(x), g_pushup(x);
        // cerr << "LOG:" << val_max[x] << '\n';
      } else if (cmd[1] == '2') {
        int x, v;
        cin >> x >> v;
        splay(x), g_splay(x);
        val[x] += v, val_max[x] += v, g_val_max[x] += v, lazy_tag[x] += v;
        // cerr << "LOG:" << val[x] << '\n';
        pushup(x), g_pushup(x);
      } else {
        int v;
        cin >> v;
        add_tot += v;
      }
    } else {
      if (cmd[1] == '1') {
        int x;
        cin >> x;
        splay(x);
        cout << val[x] + add_tot << '\n';
      } else if (cmd[1] == '2') {
        int x;
        cin >> x;
        splay(x);
        cout << val_max[x] + add_tot << '\n';
      } else {
        splay(1), g_splay(1);
        cout << g_val_max[1] + add_tot << '\n';
      }
    }
  }
}
int main() {
#ifdef LOCAL
  freopen("..\\in", "r", stdin), freopen("..\\out", "w", stdout);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  create(), solve();
  return 0;
}

/*
U x y: 加一条边,连接第x个节点和第y个节点
A1 x v: 将第x个节点的权值增加v
A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v
A3 v: 将所有节点的权值都增加v
F1 x: 输出第x个节点当前的权值
F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值
F3: 输出所有节点中,权值最大的节点的权值
*/
2020/5/2 02:29
加载中...