您的位置:首页 > 其它

BZOJ 3224: Tyvj 1728 普通平衡树

2016-12-27 09:39 323 查看

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 9629 Solved: 4091
[Submit][Status][Discuss]

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.每个数的数据范围:[-1e7,1e7]

数据如下http://pan.baidu.com/s/1jHMJwO2

Source

平衡树

[Submit][Status][Discuss]

FHQ Treap

#include <bits/stdc++.h>

const int N = 500005;

int ls
, rs
, vl
, tg
, sz
;

inline int node(int v)
{
static int t = 1;
sz[t] = 1;
vl[t] = v;
tg[t] = rand();
return t++;
}

int merge(int a, int b)
{
if (!a || !b)return a + b;
if (tg[a] > tg[b])
{
rs[a] = merge(rs[a], b);
sz[a] = 1 + sz[ls[a]] + sz[rs[a]];
return a;
}
else
{
ls[b] = merge(a, ls[b]);
sz[b] = 1 + sz[ls[b]] + sz[rs[b]];
return b;
}
}

void split(int t, int k, int &a, int &b)
{
if (!t)a = b = 0;
else
{
if (vl[t] <= k)
a = t, split(rs[t], k, rs[t], b);
else
b = t, split(ls[t], k, a, ls[t]);
sz[t] = 1 + sz[ls[t]] + sz[rs[t]];
}
}

int kth(int t, int k)
{
if (k <= sz[ls[t]])
return kth(ls[t], k);
else if (k == sz[ls[t]] + 1)
return t;
else
return kth(rs[t], k - sz[ls[t]] - 1);
}

signed main(void)
{
srand(5264);

int n, r = 0; scanf("%d", &n);

for (int a, b, x, y, z; n--; )
{
scanf("%d%d", &a, &b);

if (a == 1)
{
split(r, b, x, y);
r = merge(x, node(b));
r = merge(r, y);
}
else if (a == 2)
{
split(r, b, x, z);
split(x, b - 1, x, y);
y = merge(ls[y], rs[y]);
r = merge(x, y);
r = merge(r, z);
}
else if (a == 3)
{
split(r, b - 1, x, y);
printf("%d\n", sz[x] + 1);
r = merge(x, y);
}
else if (a == 4)
printf("%d\n", vl[kth(r, b)]);
else if (a == 5)
{
split(r, b - 1, x, y);
printf("%d\n", vl[kth(x, sz[x])]);
r = merge(x, y);
}
else
{
split(r, b, x, y);
printf("%d\n", vl[kth(y, 1)]);
r = merge(x, y);
}
}
}


#include <bits/stdc++.h>
const int N = 500005;
int ls
, rs
, vl
, tg
, sz
, tot = 1;
int node(int v) {
return vl[tot] = v, sz[tot] = 1, tg[tot] = rand(), tot++;
}
int merge(int a, int b) {
if (!a || !b)return a + b;
if (tg[a] > tg[b]) {
rs[a] = merge(rs[a], b);
sz[a] = 1 + sz[ls[a]] + sz[rs[a]];
return a;
}
else {
ls[b] = merge(a, ls[b]);
sz[b] = 1 + sz[ls[b]] + sz[rs[b]];
return b;
}
}
int split(int t, int k, int &a, int &b) {
if (!t)return a = b = 0, 0;
if (vl[t] <= k)
a = t, split(rs[t], k, rs[t], b);
else
b = t, split(ls[t], k, a, ls[t]);
return sz[t] = 1 + sz[ls[t]] + sz[rs[t]];
}
int kth(int t, int k) {
return k <= sz[ls[t]] ? kth(ls[t], k) : ((k -= sz[ls[t]] + 1) ? kth(rs[t], k) : vl[t]);
}
signed main(void) {
int n, r = 0, a, b, x, y, z;
for (scanf("%d", &n); n--; ) {
scanf("%d%d", &a, &b);
if (a == 1)
split(r, b, x, y), r = merge(merge(x, node(b)), y);
else if (a == 2)
split(r, b, x, z), split(x, b - 1, x, y), r = merge(merge(x, merge(ls[y], rs[y])), z);
else if (a == 3)
split(r, b - 1, x, y), printf("%d\n", sz[x] + 1), r = merge(x, y);
else if (a == 4)
printf("%d\n", kth(r, b));
else if (a == 5)
split(r, b - 1, x, y), printf("%d\n", kth(x, sz[x])), r = merge(x, y);
else
split(r, b, x, y), printf("%d\n", kth(y, 1)), r = merge(x, y);
}
}


@Author: YouSiki
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: