您的位置:首页 > 理论基础 > 数据结构算法

BZOJ3224 普通平衡树

2016-07-12 03:12 253 查看
题目传送门


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每行输出一个数,表示对应答案

题解

这道题很明显要用二叉排序树来进行操作,其实是裸题。不过以前没打过splay,考试时教练让我们打splay。没打出来,调了一晚上也没调出来。wwwww。熬夜打了一个treap,还要上课啊。。。。。补觉了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
const int Maxn = 101111;
struct node {
int s,v,r,cnt; int ch[2];
}N[Maxn];
int totN, root;
const int INF = 1 << 30;
void up(int u) {
int ls = N[u].ch[0], rs = N[u].ch[1];
N[u].s = N[u].cnt + N[ls].s + N[rs].s;
}

void Rot(int &u, int d) {
int t = N[u].ch[d^1];  N[u].ch[d^1] = N[t].ch[d];
N[t].ch[d] = u;
up(u); up(t); u = t;
}

void Ins(int& u,int val) {
if (!u) {
u = ++totN; N[u].v = val; N[u].cnt = 1; N[u].s = 1; N[u].r = rand();
} else {
++N[u].s; int k = val < N[u].v ? 0 : 1;
if (N[u].v == val) { ++N[u].cnt; return; }
Ins(N[u].ch[k], val);
if (N[N[u].ch[k]].r > N[u].r) Rot(u, k ^ 1);
}
}

void Del(int& u,int val) {
if (!u) return;
if (N[u].v == val) {
if (N[u].cnt > 1) { --N[u].cnt; --N[u].s; return; }
if (!N[u].ch[0] || !N[u].ch[1]) u = N[u].ch[0] + N[u].ch[1];
else {
int k = N[N[u].ch[0]].r > N[N[u].ch[1]].r;
Rot(u,k); Del(u, val);
}
} else --N[u].s, Del(N[u].ch[val < N[u].v ? 0 : 1],val);
}

int Rank(int u, int val) {
if (!u) return 0;
if (N[u].v == val) return N[N[u].ch[0]].s + 1;
if (N[u].v < val) return N[N[u].ch[0]].s + N[u].cnt + Rank(N[u].ch[1],val);
else return Rank(N[u].ch[0],val);
}

int Kth(int u,int k) {
if (!u) return 0;
if (k <= N[N[u].ch[0]].s) return Kth(N[u].ch[0],k);
if (k > N[N[u].ch[0]].s + N[u].cnt)
return Kth(N[u].ch[1],k - N[N[u].ch[0]].s - N[u].cnt);
return N[u].v;
}

int pred(int u, int val) {
if (!u) return INF;
if (val <= N[u].v) return pred(N[u].ch[0],val);
int ans = pred(N[u].ch[1],val);
if (ans == INF) ans = N[u].v;
return ans;
}

int succ(int u, int val) {
if (!u) return INF;
if (val >= N[u].v) return succ(N[u].ch[1],val);
int ans = succ(N[u].ch[0],val);
if (ans == INF) ans = N[u].v;
return ans;
}

int main() {
//freopen("A.in","r",stdin);
//freopen("A.out","w",stdout);
int n, op, x;
scanf("%d", &n);
srand(time(NULL));
while (n--) {
scanf("%d%d", &op, &x);
if (op == 1) Ins(root,x);
else if (op == 2) Del(root,x);
else if (op == 3) printf("%d\n", Rank(root,x));
else if (op == 4) printf("%d\n", Kth(root,x));
else if (op == 5) printf("%d\n", pred(root,x));
else printf("%d\n",succ(root,x));
}
return 0;
}
附:在网上看见了一个模板,把splay,treap和SBT的做法打了出来。
传送门在这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构treap