之前一直在调自己的delete 以为树写错了 结果居然离散化错了 坑坑坑坑坑 果然还是要多膜拜膜拜hlq大牛吗
多保留一个信息Min 用Min来进行元素的查找定位删除等等 其他没啥了。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000
#define INF 99999999
int a[MAXN+10], T[MAXN+10], app[MAXN+10], A[MAXN+10], n;
struct Node {
int key, sz, cnt, flag, Min;
Node *ch[2], *fa;
Node () {}
Node(int x, int y, int z, int M) {
key = x; sz = y; cnt = z; Min = M;
}
void Update() {
sz = ch[0]->sz + ch[1]->sz + cnt;
Min = min(key, min(ch[0]->Min, ch[1]->Min));
}
int cmp(int v) const {
if(v == key) return -1;
return v < key ? 0 : 1;
}
}nil(0, 0, 0, INF), *NIL = &nil;
struct Splay_Tree
{
Node *root;
Node tree[MAXN+10];
int ncnt;
void init() { root = NIL; ncnt = 0 ;};
Node *NewNode() {
Node &t = tree[++ncnt];
t.ch[0] = t.ch[1] = t.fa = NIL;
t.sz = t.cnt = 1;
t.flag = 0;
return &tree[ncnt];
}
void pushdown(Node *target) {
if(target->flag)
{
target->flag = 0;
swap(target->ch[0], target->ch[1]);
if(target->ch[0] != NIL) target->ch[0]->flag ^= 1;
if(target->ch[1] != NIL) target->ch[1]->flag ^= 1;
}
}
void Rotate(Node *x, int d)
{
Node *y = x->fa;
y->ch[!d] = x->ch[d];
if(x->ch[d] != NIL) x->ch[d]->fa = y;
x->fa = y->fa;
if(y->fa != NIL) y->fa->ch[y->fa->ch[1] == y] = x;
x->ch[d] = y;
y->fa = x;
if(y == root) root = x;
y->Update();
x->Update();
}
void splay(Node *x, Node *target)
{
Node *y, *z;
while(x->fa != target)
{
pushdown(x);
y = x->fa; y->Min = y->key;
z = y->fa; if(z != NIL) z->Min = z->key;
if(z == target) {
if(x == y->ch[0]) Rotate(x, 1);
else Rotate(x, 0);
}
else
{
if(y == z->ch[0])
if(x == y->ch[0])
Rotate(y, 1), Rotate(x, 1);
else
Rotate(x, 0), Rotate(x, 1);
else
if(x == y->ch[1])
Rotate(y, 0), Rotate(x, 0);
else
Rotate(x, 1), Rotate(x, 0);
}
x->Update();
}
pushdown(x);
}
int Find_rank(Node * target, int key)
{
pushdown(target);
if(key == target->key) return target->ch[0]->sz + 1;
if(key == target->ch[0]->Min) return Find_rank(target->ch[0], key);
return target->ch[0]->sz + 1 + Find_rank(target->ch[1], key);
}
Node *Find_kth(Node * target, int k)
{
pushdown(target);
if(k <= target->ch[0]->sz) return Find_kth(target->ch[0], k);
if(k <= target->ch[0]->sz+1) return target;
return Find_kth(target->ch[1], k-target->ch[0]->sz-1);
}
void Del(int X)
{
if(root == NIL) return ;
int key = Find_rank(X);
Node *x = Find_kth(key-1);
splay(x, NIL);
key = Find_rank(X);
Node *y = Find_kth(key+1);
splay(y, root);
Node *target = root->ch[1]->ch[0];
if(target->cnt > 1) {
target->cnt--;
target->sz--;
splay(target, NIL);
return ;
}
target->fa->ch[0] = NIL;
root->ch[1]->Update();
splay(root->ch[1], NIL);
}
void Flip(Node *target) { target->flag ^= 1; }
void Build(Node * &target, int l, int r, Node *F)
{
if(r < l) return ;
target = NewNode();
int mid = (l + r) >> 1;
target->Min = target->key = A[mid];
target->fa = F;
Build(target->ch[0], l, mid-1, target);
Build(target->ch[1], mid+1, r, target);
target->Update();
}
Node *Find_kth(int k) { return Find_kth(root, k); }
int Find_rank(int k) { return Find_rank(root, k); }
void Print(Node *target)
{
if(target == NIL) return ;
Print(target->ch[0]);
printf("%d ", target->key);
Print(target->ch[1]);
}
};
Splay_Tree sp;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); T[i] = a[i]; }
sort(T+1, T+1+n);
for(int i = 1; i <= n; i++) {
A[i+1] = lower_bound(T+1, T+1+n, a[i]) - T;
A[i+1] += app[A[i+1]]++;
}
A[1] = INF; A[n+2] = INF;
sp.Build(sp.root, 1, n+2, NIL);
for(int i = 1; i <= n; i++)
{
int R = sp.Find_rank(i);
sp.splay(sp.Find_kth(1), NIL);
sp.splay(sp.Find_kth(R+1), sp.root);
sp.Flip(sp.root->ch[1]->ch[0]);
if(i!=n) printf("%d ", R-1+i-1);
else printf("%d", R-1+i-1);
sp.Del(i);
}
}