## bzoj 3224: Tyvj 1728 普通平衡树 替罪羊树

1. 插入x数
2. 删除x数(若有多个相同的数，因只删除一个)
3. 查询x数的排名(若有多个相同的数，因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x，且最大的数)
6. 求x的后继(后继定义为大于x，且最小的数)

#include <bits/stdc++.h>

using namespace std;
#define MAXN 100010
const double alpha = 0.75;
struct node
{
int sz, cover, val;
bool exist;
node* ch[2];
node()
{
ch[0] = ch[1] = NULL;
exist = false;
sz = cover = 0;
}
node(int val):val(val)
{
sz = cover = 1;
exist = true;
ch[0] = ch[1] = NULL;
}
void pushUp(node* tmp)
{
sz += tmp->sz;
cover += tmp->cover;
}
{
int tmpL = ch[0]?ch[0]->cover:0;
int tmpR = ch[1]?ch[1]->cover:0;
if(tmpL > cover * alpha + 5 ||
tmpR > cover * alpha + 5)
return true;
return false;
}
};
node* root = NULL;
void add(node*& p, int val, node** flag)
{
if(p == NULL) {
p = new node(val);
return ;
}
p->sz++;
p->cover++;
flag = &p;
}
}
void Erase(node* p, int k)
{
int x = p->ch[0]?p->ch[0]->sz:0;
int tmp = x + (int)(p->exist);
p->sz--;
if(p->exist && tmp == k) {
p->exist = false;
return ;
}
if(k <= tmp) {
Erase(p->ch[0], k);
} else {
Erase(p->ch[1], k - tmp);
}
}
void traval(node*& p, vector<node*>& v)
{
if(p == NULL)
return ;
traval(p->ch[0], v);
if(p->exist) {
v.push_back(p);
}
traval(p->ch[1], v);
}
void divide(node*& p, vector<node*>& v, int l, int r)
{
if(l > r)
return ;
if(p == NULL)
p = new node();
int mid = l + r >> 1;
p = v[mid];
divide(p->ch[0], v, l, mid - 1);
divide(p->ch[1], v, mid + 1, r);
if(p->ch[0])
p->pushUp(p->ch[0]);
if(p->ch[1])
p->pushUp(p->ch[1]);
if(p->exist)
p->sz++;
p->cover++;
}
void rebuild(node*& p)
{
vector <node*> v;
traval(p, v);
divide(p, v, 0, v.size()-1);
}
int Rank(node*& p, int x)
{
if(p == NULL)
return 1;
int ret = 0;
if(p->val >= x) {
ret = Rank(p->ch[0], x);
} else {
int tmp = (p->ch[0])?p->ch[0]->sz:0;
ret = tmp + (int)p->exist;
ret += Rank(p->ch[1], x);
}
return ret;
}
int Kth(node*& p, int k)
{
if(p == NULL)
return 1;
int tmp = (p->ch[0])?p->ch[0]->sz:0;
if(p->exist && tmp + 1 == k)
return p->val;
if(tmp >= k) {
return Kth(p->ch[0], k);
} else {
return Kth(p->ch[1], k - tmp - p->exist);
}
}
void Insert(int val)
{
node** flag = NULL;
if(flag != NULL) {
rebuild(*flag);
}
}
void Erase(int k)
{
Erase(root, k);
if((double)root->sz < (double)(alpha*root->cover))
rebuild(root);
}
int main()
{
int n, sign, x;
cin>>n;
while(n--) {
scanf("%d%d", &sign, &x);
switch(sign) {
case 1: Insert(x);break;
case 2: Erase(root, Rank(root, x));break;
case 3: printf("%d\n", Rank(root, x));break;
case 4: printf("%d\n", Kth(root, x));break;
case 5: printf("%d\n", Kth(root, Rank(root, x) - 1));break;
case 6: printf("%d\n", Kth(root, Rank(root, x + 1)));break;
}
}
return 0;
}

posted on 2016-11-17 15:03  yohaha  阅读(130)  评论(0编辑  收藏  举报