题目链接:https://cn.vjudge.net/problem/HDU-1890
题意:每次将第i个位置到第i大的数所在位置 之间的数进行翻转,输出的是第i大的数所在的位置
题解:按照1-n建树,原序列排序,每次把节点 a[i].id 放到顶部,位置即为左子树数目+i,然后删除顶部节点
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
struct Splaytree {
int nex[N][2];
int f[N];
int sz[N]; // 子树节点个数
int val[N]; // 当前节点的值
int cnt[N]; // 当前节点个数
int rev[N]; // 翻转标记
int root;
int tot;
void init() {
root = 0;
tot = 0;
f[0] = sz[0] = nex[0][0] = nex[0][1] = 0;
rev[0] = 0;
cnt[0] = 0;
}
void newnode(int rt, int v, int fa) {
f[rt] = fa;
sz[rt] = 1;
val[rt] = v;
cnt[rt] = 1;
rev[rt] = 0;
nex[rt][0] = nex[rt][1] = 0;
}
void delnode(int rt) {
f[rt] = sz[rt] = val[rt] = cnt[rt] = 0;
nex[rt][0] = nex[rt][1] = 0;
}
void pushup(int rt) {
if(!rt) return;
sz[rt] = cnt[rt];
if(nex[rt][0]) sz[rt] += sz[nex[rt][0]];
if(nex[rt][1]) sz[rt] += sz[nex[rt][1]];
}
void build(int &rt, int l, int r, int fa) { // 构建
if(l > r) return;
int mid = (l + r) >> 1;
rt = mid;
val[rt] = mid;
newnode(rt, val[rt], fa);
cnt[rt] = 1;
build(nex[rt][0], l, mid - 1, rt);
build(nex[rt][1], mid + 1, r, rt);
pushup(rt);
}
void update_rev(int rt) {
if(rt) {
nex[rt][0] ^= nex[rt][1] ^= nex[rt][0] ^= nex[rt][1];
rev[rt] ^= 1;
}
}
void pushdown(int rt) {
if(!rt) return;
if(rev[rt]) {
update_rev(nex[rt][0]);
update_rev(nex[rt][1]);
rev[rt] = 0;
}
}
void rotate(int x, int k) { // 0:左旋 1:右旋
int y = f[x];
int z = f[y];
pushdown(y);
pushdown(x);
nex[y][!k] = nex[x][k];
if(nex[x][k]) f[nex[x][k]] = y;
f[x] = z;
if(z) nex[z][nex[z][1] == y] = x;
f[y] = x;
nex[x][k] = y;
pushup(y);
pushup(x);
}
void splay(int x, int goal) { // x 旋转到 goal下面
while(f[x] != goal) {
if(f[f[x]] == goal) rotate(x, nex[f[x]][0] == x);
else {
int y = f[x], z = f[y];
int K = (nex[z][0] == y);
if(nex[y][K] == x) rotate(x, !K), rotate(x, K);
else rotate(y, K), rotate(x, K);
}
}
pushup(x);
if(goal == 0) root = x;
}
int rt_right(int rt){ // 子树 最右
for(pushdown(rt); nex[rt][1]; pushdown(rt)) rt = nex[rt][1];
return rt;
}
void delete_rt() { // 删除 根节点
if(nex[root][0] == 0) {
root = nex[root][1];
f[root] = 0;
} else {
int y = rt_right(nex[root][0]);
splay(y, root);
nex[y][1] = nex[root][1];
f[nex[root][1]] = y;
root = y;
f[root] = 0;
pushup(root);
}
}
}p;
int n;
struct node {
int x, id;
bool operator <(const node &b)const {
if(x == b.x) return id < b.id;
else return x < b.x;
}
}a[N];
int main() {
while(~scanf("%d", &n) && n) {
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i].x);
a[i].id = i;
}
sort(a + 1, a + 1 + n);
p.init();
p.build(p.root, 1, n, 0);
p.pushup(p.root);
for(int i = 1; i <= n; i++) {
p.splay(a[i].id, 0);
printf("%d%c", p.sz[p.nex[p.root][0]] + i, " \n"[i == n]);
p.update_rev(p.nex[p.root][0]);
p.delete_rt();
}
}
return 0;
}