题目

你需要写一种数据结构支援以下操作。

  1. 插入元素。
  2. 删除元素。
  3. 查询元素的排名。
  4. 查询第k小的元素。
  5. 查询元素前趋。
  6. 查询元素后继。

题解

BBST裸题。

代码

#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
#ifdef D
const int maxn = 100;
#else
const int maxn = 100005;
#endif
int ch[maxn][2], fa[maxn], size[maxn], data[maxn], cnt[maxn];
int rt, n, m;
ll sz = 0;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void update(int x) {
size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
}
inline void zig(int x) {
int y = fa[x], z = fa[y], l = (ch[y][1] == x), r = l ^ 1;
fa[ch[y][l] = ch[x][r]] = y;
fa[ch[x][r] = y] = x;
fa[x] = z;
if (z)
ch[z][ch[z][1] == y] = x;
update(y);
}
inline void splay(int x, int aim = 0) { //调整x成为aim的儿子
for (int y; (y = fa[x]) != aim; zig(x)) {
if (fa[y] != aim)
zig((ch[y][0] == x) == (ch[fa[y]][0] == y) ? y : x);
}
if (aim == 0)
rt = x;
update(x);
}
inline void insert(int v) {
int x = rt;
if (rt == 0) {
rt = x = ++sz;
data[x] = v;
fa[x] = ch[x][0] = ch[x][1] = 0;
size[x] = cnt[x] = 1;
return;
}
while (x) {
size[x]++;
if (v == data[x]) {
cnt[x]++;
return;
}
int &y = ch[x][v >= data[x]];
if (y == 0) {
y = ++sz;
data[y] = v;
fa[y] = x;
ch[y][0] = ch[y][1] = 0;
size[y] = cnt[y] = 1;
x = y;
break;
}
x = y;
}
splay(x);
}
int rank(int v) {
int ret = 0, ans, x = rt;
while (x) {
if (v > data[x]) {
ret += size[ch[x][0]] + cnt[x];
x = ch[x][1];
} else {
if (v == data[x]) {
return ret + size[ch[x][0]] + 1;
}
x = ch[x][0];
}
}
}
int kth(int v) {
int x = rt;
while (x) {
if (v >= size[ch[x][0]] + 1 && v <= size[ch[x][0]] + cnt[x])
return data[x];
if (v > size[ch[x][0]] + cnt[x]) {
v -= size[ch[x][0]] + cnt[x];
x = ch[x][1];
} else
x = ch[x][0];
}
}
int pre(int v) {
int ans;
for (int y = rt; y;)
if (data[y] < v)
ans = data[y], y = ch[y][1];
else
y = ch[y][0];
return ans;
}
int succ(int v) {
int ans;
for (int y = rt; y;)
if (data[y] <= v)
y = ch[y][1];
else
ans = data[y], y = ch[y][0];
return ans;
}
inline void del(int v) {
int x = rt;
while (x) {
size[x]--;
if (data[x] == v) {
cnt[x]--;
break;
}
int &y = ch[x][v >= data[x]];
x = y;
}
if (cnt[x] != 0)
return;
splay(x);
if (ch[x][0] == 0) {
rt = ch[x][1];
fa[rt] = 0;
return;
}
if (ch[x][1] == 0) {
rt = ch[x][0];
fa[rt] = 0;
return;
}
x = ch[rt][0];
while (ch[x][1])
x = ch[x][1];
splay(x, rt);
ch[x][1] = ch[rt][1];
fa[ch[x][1]] = x;
size[x] = size[rt] - 1;
fa[x] = 0;
rt = x;
}
int main() {
#ifdef DEBUG
freopen("input", "r", stdin);
#endif
scanf("%d", &n);
rt = sz = 0;
while (n--) {
int opt = read();
if (opt == 1) {
int x = read();
insert(x); // O(log n)
} else if (opt == 2) {
int x = read();
del(x); // O(log n)
} else if (opt == 3) {
int k = read();
printf("%d\n", rank(k));
} else if (opt == 4) {
int k = read();
printf("%d\n", kth(k));
} else if (opt == 5) {
int x = read();
printf("%d\n", pre(x));
} else if (opt == 6) {
int x = read();
printf("%d\n", succ(x));
}
}
}

[bzoj3224]Tyvj 1728 普通平衡树——splay模板的更多相关文章

  1. bzoj3224: Tyvj 1728 普通平衡树(splay)

    3224: Tyvj 1728 普通平衡树 题目:传送门 题解: 啦啦啦啦又来敲个模版水经验啦~ 代码: #include<cstdio> #include<cstring> ...

  2. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

  3. bzoj3224: Tyvj 1728 普通平衡树(平衡树)

    bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...

  4. 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  5. bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5354  Solved: 2196[Submit][Sta ...

  6. BZOJ3224 洛谷3369 Tyvj 1728 普通平衡树 splay

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3224 题意概括 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. ...

  7. 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会

    平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...

  8. bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

    (其实今天好热啊? 题目大意:插入,删除,k小,前驱后继,数的排名. splay和treap裸题...过几天补个treap的 splay: #include<iostream> #incl ...

  9. 【Splay】bzoj3224 Tyvj 1728 普通平衡树

    #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> us ...

随机推荐

  1. 【多校联合】(HDU6045)Is Derek lying?

    分析 之前没有想到题目解法,看了题解才会,记录一下思考过程. 这条题目的实质是,在满足合法的情况下,有没有a和d的可行解?也就是说,不要仅仅附在表面的思考逻辑条件,而是要思考实际的数学表达. 转化为数 ...

  2. idea在Maven Projects中显示灰色的解决办法

    问题描述: 在使用idea的过程中,遇到其中一个maven模块变成灰色,如下所示: 问题解决: 造成这个的原因可能是忽略了maven模块. 可以尝试如下解决方法:在idea中进入Settings–&g ...

  3. Qt 隐藏标题栏可移动升级版

    在最出的时候,在Qt程序隐藏标题栏的情况下,实现界面可拖拽移动,是鼠标在在程序界面的任意位置都可以,现在这个版本是需要鼠标在程序界面的特定位置开可以 上代码 static QPoint last(0, ...

  4. (转)基于CUDA的GPU光线追踪

    作者:Asixa 链接:https://zhuanlan.zhihu.com/p/55855479 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.     替STL. ...

  5. [USACO19JAN]Cow Poetry

    题面 Solution: 这是一道很好的dp题. 一开始看不懂题面没有一点思路,看了好久题解才看懂题目... \(y[i]\) 为第 \(i\) 个词结尾,\(l[i]\) 为第 \(i\) 个词长度 ...

  6. 无法注册DLL/OCX:regsvr32 failed with exit code 0x5

    最近在服务器上装一个等值线控件,确报错: RegSvr32 failed with exit code 0x5   尝试解决方法1: 在cmd下 运行for %1 in (%windir%\syste ...

  7. shell语句for循环

    一:常用格式 格式一 for 变量 do 语句 done 格式二 for 变量 in 列表 do 语句 done 格式三 for ((变量=初始值; 条件判断; 变量变化)) do 语句 done 二 ...

  8. picker组件,mode=date,苹果机年份从1开始

    由于在IOS上复制图片不方便, 所以用了张别的网站的图 这是在没有设置value和start的情况下出现的,安卓机上显示是好的.尝试完网上相关说法, 发现都不中! 通过各种挣扎啊!~ 心里苦啊~ 复制 ...

  9. 在Android Studio中创建(或添加)第一个Hello World应用程序

    下面我们将使用Android Studio创建第一个简单的Hello World应用程序. 1.打开Android Studio,加载画面如下图所示:   2.选择”Start a new Andro ...

  10. jquery在页面加载完成后再append的元素事件无效问题

    最近遇到一个问题,jquery在页面加载完成后再append的元素,append元素上有onclick事件,但是在append的元素上怎么点击都不会触发onclick事件.就如: <ul cla ...