好像是哪里死循环了。。
因为这题不用堆的操作,所以只是用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: 输出所有节点中,权值最大的节点的权值
*/