您的位置:首页 > 其它

BZOJ 3224: Tyvj 1728 普通平衡树

2017-04-15 18:57 363 查看

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

1. 插入x数

2. 删除x数(若有多个相同的数,因只删除一个)

3. 查询x数的排名(若有多个相同的数,因输出最小的排名)

4. 查询排名为x的数

5. 求x的前驱(前驱定义为小于x,且最大的数)

6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10

1 106465

4 1

1 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-2e9,2e9]

分析

就是学splay模板而已,但我感觉常数好大,之后慢慢改改

代码

#include <bits/stdc++.h>

#define N 500000

struct
{
int fa;
int son[3];
int size[3];
int count;
int cover;
}t
;

int n;
int node;
int root;

void rotate(int x,int w)
{
int f = t[x].fa;
int g = t[f].fa;
t[f].son[3 - w] = t[x].son[w];
if (t[x].son[w])
t[t[x].son[w]].fa = f;
t[x].fa = g;
t[f].size[3 - w] = t[x].size[w];
t[x].size[w] += t[f].size[w] + 1;
if (g)
{
if (f == t[g].son[1])
t[g].son[1] = x;
else t[g].son[2] = x;
}
t[f].fa = x;
t[x].son[w] = f;
}

void splay(int x)
{
int y;
while (t[x].fa)
{
y = t[x].fa;
if (!t[y].fa)
{
if (x == t[y].son[1])
rotate(x,2);
else rotate(x,1);
continue;
}
if (y == t[t[y].fa].son[1])
{
if (x == t[y].son[1])
rotate(y,2), rotate(x,2);
else rotate(x,1), rotate(x,2);
}
else
{
if (x == t[y].son[2])
rotate(y,1), rotate(x,1);
else rotate(x,2), rotate(x,1);
}
}
root = x;
}

void insert(int x,int add)
{
if (t[x].cover >= add)
{
if (!t[x].son[1])
{
t[x].son[1] = ++node;
t[node].cover = add;
t[node].fa = x;
if (!root)
root = node;
}
else insert(t[x].son[1],add);
t[x].size[1]++;
}
else
{
if (!t[x].son[2])
{
t[x].son[2] = ++node;
t[node].cover = add;
t[node].fa = x;
if (!root)
root = node;
}
else insert(t[x].son[2],add);
t[x].size[2]++;
}
}

void del(int x,int dec)
{
if (!x)
return;
if (dec == t[x].cover)
{
splay(x);

if (!t[x].son[1] && !t[x].son[2])
{
root = 0;
return;
}

if (!t[x].son[1])
{
root = t[x].son[2];
t[t[x].son[2]].fa = 0;
return;
}

if (!t[x].son[2])
{
root = t[x].son[1];
t[t[x].son[1]].fa = 0;
return;
}

int f = t[x].son[1];
int tmp = t[x].son[2];
while (t[f].son[2])
f = t[f].son[2];
splay(f);
t[f].son[2] = tmp;
t[tmp].fa = f;
return;
}
if (dec < t[x].cover)
del(t[x].son[1],dec);
else del(t[x].son[2],dec);
}

int kth(int x,int add,int now)
{
insert(root,add);
splay(node);
int ans = t[node].size[1] + 1;
del(node,add);
return ans;
}

int findK(int x,int k)
{
if (k == t[x].size[1] + 1)
return t[x].cover;
if (k <= t[x].size[1])
return findK(t[x].son[1],k);
else return findK(t[x].son[2],k - t[x].size[1] - 1);
}

bool flag;

int pred(int x,int k)
{
int f = t[x].son[1];
if (!f)
return 0;
while (t[f].son[2])
f = t[f].son[2];
if (t[f].cover != k)
flag = 1;
return f;
}

int succ(int x,int k)
{
int f = t[x].son[2];
if (!f)
return 0;
while (t[f].son[1])
f = t[f].son[1];
if (t[f].cover != k)
flag = 1;
return f;
}

int main()
{
int n;
scanf("%d",&n);
for (int i = 1; i <= n; i++)
{
int opt,x;
scanf("%d%d",&opt,&x);
if (opt == 1)
insert(root,x), splay(node);
if (opt == 2)
del(root,x);
if (opt == 3)
printf("%d\n",kth(root,x,0));
if (opt == 4)
printf("%d\n",findK(root,x));
if (opt == 5)
{
int ans;
insert(root,x);
splay(node);
for (flag = 0, ans = pred(root,x); !flag || !ans; splay(ans), ans = pred(root,x));
del(root,x);
printf("%d\n",t[ans].cover);
}
if (opt == 6)
{
int ans;
insert(root,x);
splay(node);
for (flag = 0, ans = succ(root,x); !flag || !ans; splay(ans), ans = succ(root,x));
del(root,x);
printf("%d\n",t[ans].cover);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: