# BZOJ 3223 文艺平衡树

## 题解

1. which(u) ? xxx, xxx : xxx, xxx; 冒号左右的式子都要打括号；
2. 这里的 Find 函数找的是“序列中的第x个点”，不是值第x大的点。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}

const int N = 100005;
int n, m;
int root = 1, idx, id[N] = {-1}, sze[N], ls[N], rs[N], fa[N], lazy[N];
#define which(x) (ls[fa[(x)]] == (x))

void upt(int u){
sze[u] = sze[ls[u]] + sze[rs[u]] + 1;
}
void rotate(int u){
int v = fa[u], w = fa[v], b = which(u) ? rs[u] : ls[u];
if(w) which(v) ? ls[w] = u : rs[w] = u;
which(u) ? (ls[v] = b, rs[u] = v) : (rs[v] = b, ls[u] = v);
if(b) fa[b] = v;
fa[v] = u, fa[u] = w;
upt(v), upt(u);
}
void splay(int u, int tar){
while(fa[u] != tar){
if(fa[fa[u]] != tar){
if(which(u) == which(fa[u])) rotate(fa[u]);
else rotate(u);
}
rotate(u);
}
if(!tar) root = u;
}
void swap_son(int u){
if(!u) return;
lazy[u] ^= 1;
swap(ls[u], rs[u]);
upt(u);
}
void pushdown(int u){
if(!lazy[u]) return;
swap_son(ls[u]), swap_son(rs[u]);
lazy[u] = 0;
}
int find(int x){
int u = root;
pushdown(u);
while(sze[ls[u]] != x && u){
if(sze[ls[u]] >= x + 1) u = ls[u];
else x -= sze[ls[u]] + 1, u = rs[u];
pushdown(u);
}
return u;
}
void reverse(int l, int r){
splay(find(l - 1), 0);
splay(find(r + 1), root);
swap_son(ls[rs[root]]);
}
int build(int l, int r){
int mid = (l + r) >> 1, u = ++idx;
id[u] = mid;
if(mid > l) ls[u] = build(l, mid - 1), fa[ls[u]] = u;
if(mid < r) rs[u] = build(mid + 1, r), fa[rs[u]] = u;
upt(u);
return u;
}
void out(int u){
pushdown(u);
if(ls[u]) out(ls[u]);
if(id[u] && id[u] <= n) write(id[u]), space;
if(rs[u]) out(rs[u]);
}

int main(){