您的位置:首页 > 其它

BZOJ 3224: Tyvj 1728 普通平衡树

2016-12-09 09:03 441 查看

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 9275 Solved: 3932
[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]

小生的第二道平衡树板子题。

#include <bits/stdc++.h>

const int inf = 2e9 + 9;

class Splay {
public:
Splay(void) {
root = NULL;
for (top = 0; top < siz; ++top)
stk[top] = tree + top;
}

inline void insert(int val) {
if (find(val) != NULL)
++root->count, update(root);
else if (root == NULL)
root = newnode(val, NULL);
else
splay(insert(root, val), NULL);
}

inline void erase(int val) {
if (find(val) != NULL)
erase(root, 1);
}

inline int rnk(int val) {
if (find(val) != NULL)
return size(root->son[0]) + 1;
else
return 0;
}

inline int qry(int kth) {
if (size(root) < kth)
return 0;
for (node *t = root; t; ) {
if (kth > size(t->son[0])) {
kth -= size(t->son[0]);
if (kth >= 1 && kth <= t->count)
return t->value;
else
kth -= t->count, t = t->son[1];
}
else
t = t->son[0];
}
}

inline int prv(int val) {
int ret = -inf;
for (node *t = root; t; ) {
if (t->value < val)
if (ret < t->value)
ret = t->value;
t = t->son[val > t->value];
}
return ret;
}

inline int nxt(int val) {
int ret = inf;
for (node *t = root; t; ) {
if (t->value > val)
if (ret > t->value)
ret = t->value;
t = t->son[val >= t->value];
}
return ret;
}

private:
struct node {
int size;
int value;
int count;
node *father;
node *son[2];
}*root;

const static int siz = 1e5 + 5;

node tree[siz], *stk[siz]; int top;

inline node *newnode(int v, node *f) {
node *t = stk[--top];
t->size = 1;
t->value = v;
t->count = 1;
t->father = f;
t->son[0] = NULL;
t->son[1] = NULL;
return t;
}

inline void freenode(node *t) {
stk[top++] = t;
}

inline int size(node *t) {
return t == NULL ? 0 : t->size;
}

inline void update(node *t) {
if (t != NULL) {
t->size = t->count;
t->size += size(t->son[0]);
t->size += size(t->son[1]);
}
}

inline bool son(node *f, node *s) {
if (f == NULL)
return 0;
return f->son[1] == s;
}

inline void connect(node *f, node *s, bool k) {
if (f != NULL)
f->son[k] = s;
else
root = s;
if (s != NULL)
s->father = f;
}

inline void rotate(node *t) {
node *f = t->father;
node *g = f->father;
bool a = son(f, t), b = !a;
connect(f, t->son[b], a);
connect(g, t, son(g, f));
connect(t, f, b);
update(f);
update(t);
}

inline void splay(node *t, node *p) {if (t) {
while (t->father != p) {
node *f = t->father;
node *g = f->father;
if (g == p)
rotate(t);
else {
if (son(g, f) ^ son(f, t))
rotate(t), rotate(t);
else
rotate(f), rotate(t);
}
}
}
}

inline node *find(int val) {
node *ret = root;
while (ret != NULL && ret->value != val)
ret = ret->son[val >= ret->value];
return splay(ret, NULL), ret;
}

node *insert(node *t, int val) {
node *ret = t->son[val >= t->value];
if (ret == NULL)
ret = t->son[val >= t->value] = newnode(val, t);
else
ret = insert(ret, val);
return update(t), ret;
}

inline void erase(node *t) {
if (t->son[0] == NULL)
connect(NULL, t->son[1], 0), update(root);
else if (t->son[1] == NULL)
connect(NULL, t->son[0], 0), update(root);
else {
node *p = t->son[0];
while (p->son[1] != NULL)
p = p->son[1];
splay(p, t);
connect(NULL, p, 0);
connect(p, t->son[1], 1);
update(root);
}
freenode(t);
}

inline void erase(node *t, int k) {
t->count -= k;
if (t->count <= 0)
erase(t);
else
update(t);
}
}S;

inline int next(void) {
int ret = 0;
int neg = false;
int bit = getchar();
while (bit <= '0') {
if (bit == '-')
neg ^= true;
bit = getchar();
}
while (bit >= '0') {
ret = ret*10 + bit - '0';
bit = getchar();
}
return neg ? -ret : ret;
}

signed main(void) {
for (int n = next(); n--; ) {
int opt = next();
int num = next();
if (opt == 1)
S.insert(num);
else if (opt == 2)
S.erase(num);
else if (opt == 3)
printf("%d\n", S.rnk(num));
else if (opt == 4)
printf("%d\n", S.qry(num));
else if (opt == 5)
printf("%d\n", S.prv(num));
else
printf("%d\n", S.nxt(num));
}
}


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