rt。今天上午写了一个文艺平衡树板子,本地编译不过,但是交上去却过了。于是我调整了一下语言环境,发现 C++ 98 / 11 / 14 代码都会 T,但是 C++ 17 / 20 都可以过。
我觉得可能是因为代码 UB 的原因。求解答。
(本地输出了一下 sz 数组发现不对)。
#include <iostream>
#include <cstring>
#include <cstdio>
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
using namespace std;
const int N = 100010;
int n, m, root, idx;
int ch[N][2], fa[N], rev[N], sz[N], val[N];
#define ls ch[x][0]
#define rs ch[x][1]
void pushup(int x) {
sz[x] = 1;
if (ls) sz[x] += sz[ls];
if (rs) sz[x] += sz[rs];
}
void pushrev(int x) { swap(ls, rs); rev[x] ^= 1; }
void pushdown(int x) { if (rev[x]) {
if (ls) pushrev(ls); if (rs) pushrev(rs); rev[x] = 0; }
}
void rotate(int x) {
int y = fa[x], z = fa[y], k = ch[y][1] == x, &w = ch[x][k ^ 1];
fa[fa[fa[ch[w = y][k] = w] = y] = x] = z, ch[z][ch[z][1] == y] = x;
pushup(y), pushup(x);
}
void splay(int x, int k = 0) {
for (int y, z; fa[x] != k; rotate(x)) {
y = fa[x], z = fa[y];
if (z != k) rotate(((ch[y][1] == x) ^ (ch[z][1] == y)) ? y : x);
} if (!k) root = x;
}
int kth(int k, int x = root) {
while (1) {
pushdown(x);
if (sz[ls] >= k) x = ls;
else if (sz[ls] + 1 == k) return x;
else k -= sz[ls] + 1, x = rs;
}
}
void insert(int v, int x = root, int p = 0) {
while (x) p = x, x = ch[x][v > val[x]];
x = ++ idx; if (p) ch[p][v > val[x]] = x;
fa[x] = p, val[x] = v, sz[x] = 1; splay(x);
}
void print(int x) {
pushdown(x);
if (ls) print(ls);
if (val[x] >= 1 and val[x] <= n) printf("%d ", val[x]);
if (rs) print(rs);
}
int main() {
scanf("%d%d", &n, &m);
rep(i, 0, n + 1) insert(i);
rep(i, 1, m) {
int l, r; scanf("%d%d", &l, &r);
l = kth(l), r = kth(r + 2);
splay(l), splay(r, l); pushrev(ch[r][0]);
} print(root); return 0;
}