传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

保存splay模版

一刻不停写了一个小时多一点,幸好一遍过了!(其实带着freopen wa了一次)

添加一个易出bug的地方叭(鉴于曾经有次这么错过):此题平衡树里可以用重复值,我是用tm保存出现的次数,因此在求第k大时,千万小心循环结束条件!

#include <cstdio>
#include <algorithm> const int maxn = 200005; int fa[maxn], ch[maxn][2], key[maxn], tm[maxn], siz[maxn], root, cnt, t1, t2; inline void pushup(int x) {
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + tm[x];
}
inline void rotate(int x) {
int y = fa[x];
if (y == ch[fa[y]][0]) {
ch[fa[y]][0] = x;
}
else {
ch[fa[y]][1] = x;
}
fa[x] = fa[y];
int dir = x == ch[y][1];
ch[y][dir] = ch[x][dir ^ 1];
fa[ch[x][dir ^ 1]] = y;
ch[x][dir ^ 1] = y;
fa[y] = x;
pushup(y);
pushup(x);
}
inline void splay(int x) {
int p, flag1, flag2;
while (fa[x]) {
p = fa[x];
if (!fa[p]) {
rotate(x);
}
else {
flag1 = x == ch[p][1];
flag2 = p == ch[fa[p]][1];
if (flag1 ^ flag2) {
rotate(x);
}
else {
rotate(p);
}
rotate(x);
}
}
root = x;
}
bool ist(int x, int val, int p, int dir) {
if (!x) {
key[++cnt] = val;
tm[cnt] = 1;
siz[cnt] = 1;
fa[cnt] = p;
ch[p][dir] = cnt;
return true;
}
if (val < key[x]) {
bool rt = ist(ch[x][0], val, x, 0);
pushup(x);
return rt;
}
else if (val > key[x]) {
bool rt = ist(ch[x][1], val, x, 1);
pushup(x);
return rt;
}
else {
++tm[x];
++siz[x];
return false;
}
}
inline int fndmin(int x) {
int rt = x, mn = key[x];
for (int i = ch[x][0]; i; i = ch[i][0]) {
if (mn > key[i]) {
mn = key[rt = i];
}
}
return rt;
}
inline int fndmax(int x) {
int rt = x, mx = key[x];
for (int i = ch[x][1]; i; i = ch[i][1]) {
if (mx < key[i]) {
mx = key[rt = i];
}
}
return rt;
}
void del(int x, int value) {
if (!x) {
return;
}
if (value < key[x]) {
del(ch[x][0], value);
pushup(x);
}
else if (value > key[x]) {
del(ch[x][1], value);
pushup(x);
}
else if (tm[x] > 1) {
--tm[x];
--siz[x];
}
else {
splay(x);
fa[ch[x][0]] = fa[ch[x][1]] = 0;
if (!ch[x][0]) {
root = ch[x][1];
}
else if (!ch[x][1]) {
root = ch[x][0];
}
else {
root = fndmax(ch[x][0]);
splay(root);
fa[ch[x][1]] = root;
ch[root][1] = ch[x][1];
pushup(root);
}
}
}
inline int qianqu(int val) {
if (ist(root, val, 0, 0)) {
splay(cnt);
}
int x = root;
while (val != key[x]) {
x = ch[x][val > key[x]];
}
splay(x);
x = key[fndmax(ch[x][0])];
del(root, val);
return x;
}
inline int houji(int val) {
if (ist(root, val, 0, 0)) {
splay(cnt);
}
int x = root;
while (val != key[x]) {
x = ch[x][val > key[x]];
}
splay(x);
x = key[fndmin(ch[x][1])];
del(root, val);
return x;
}
inline int getrank(int val) {
int x = root;
while (key[x] != val) {
x = ch[x][val > key[x]];
}
splay(x);
return siz[ch[x][0]] + 1;
}
inline int getnum(int rank) {
int x = root;
while (rank <= siz[ch[x][0]] || rank > siz[ch[x][0]] + tm[x]) {
if (rank <= siz[ch[x][0]]) {
x = ch[x][0];
}
else {
rank -= siz[ch[x][0]] + tm[x];
x = ch[x][1];
}
}
return key[x];
} int main(void) {
int n;
scanf("%d", &n);
while (n--) {
scanf("%d%d", &t1, &t2);
if (t1 == 1) {
if (ist(root, t2, 0, 0)) {
splay(cnt);
}
}
else if (t1 == 2) {
del(root, t2);
}
else if (t1 == 3) {
printf("%d\n", getrank(t2));
}
else if (t1 == 4) {
printf("%d\n", getnum(t2));
}
else if (t1 == 5) {
printf("%d\n", qianqu(t2));
}
else {
printf("%d\n", houji(t2));
}
}
return 0;
}

  

_bzoj3224 Tyvj 1728 普通平衡树【Splay】的更多相关文章

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

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

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

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

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

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

  4. bzoj 3224/Tyvj 1728 普通平衡树(splay)

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

  5. BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解

    下面给出Splay的实现方法(复杂度证明什么的知道是 nlogn 就可以啦) 首先对于一颗可爱的二叉查找树,是不能保证最坏nlogn的复杂度(可以想象把一个升序序列插入) (二叉查找树保证左子树元素大 ...

  6. [bzoj3224]Tyvj 1728 普通平衡树——splay模板

    题目 你需要写一种数据结构支援以下操作. 插入元素. 删除元素. 查询元素的排名. 查询第k小的元素. 查询元素前趋. 查询元素后继. 题解 BBST裸题. 代码 #include <cstdi ...

  7. BZOJ 3224: Tyvj 1728 普通平衡树 or 洛谷 P3369 【模板】普通平衡树-Splay树模板题

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 22483  Solved: 10130[Submit][S ...

  8. BZOJ_3224 Tyvj 1728 普通平衡树 【离散化+权值线段树】

    一 题面 Tyvj 1728 普通平衡树 二 分析 比较明显是可以用平衡二叉搜索树(splay)做的. 用权值线段树做,前提就是要先离散化,因为权值线段树维护的值域信息. 板子. 三 AC代码 #in ...

  9. 3224: Tyvj 1728 普通平衡树(新板子)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17048  Solved: 7429[Submit][St ...

随机推荐

  1. python读取大文件的方法

    python计算文件的行数和读取某一行内容的实现方法 :最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的 ...

  2. Linux 命令 sudo

    sudo 这个命令. 是为了 让 普通用户 ,也能够以root的身份来运行 操作, 而这些普通用户 又不须要知道root的password. 在 sudo 运行命令的时候. 仅仅须要 输入自己的pas ...

  3. ASP.NET Web Pages - 教程

    ASP.NET Web Pages - 教程 ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器脚本创建网页和网站的开发框架. ASP.NET 支持三种不同的开发模式:Web ...

  4. ACdream原创群赛(13)のwuyiqi退役专场 C True love

    True love Time Limit: 4000/2000 MS (Java/Others)     Memory Limit:128000/64000 KB (Java/Others) Prob ...

  5. EA生成实体类代码

    引言 在做机房个人版重构的时候,就听说了EA是一个强大的软件.仅仅只是知道的时候,已经画完了图,没有怎么用EA其它的功能,所以一直没有见识过罢了.如今到了机房合作了,想到EA一定要好好用,这样能省不少 ...

  6. Windows Server 2012 R2 安装.NET Framework 3.5报错

    简单记录一下,Windows Server 2012 R2 安装.NET Framework 3.5报错,下面是解决方法 载入ISO文件Windows Server 2012 R2,而且在安装的过程中 ...

  7. PHP引用是什么?

    引用是什么 在 PHP 中引用意味着用不同的名字访问同一个变量内容.这并不像 C 的指针,替代的是,引用是符号表别名.注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字.最 ...

  8. Java SE之break和continue标签

    文是学习网络上的文章时的总结,感谢大家无私的分享. Java没有提供goto功能,可是保留了gotokeyword. 在java中能够使用break标签和continue标签功能实现简版的goto功能 ...

  9. Cocos2d-x 3.2 Lua演示样例CurrentLanguageTest(当前语言环境)

    Cocos2d-x 3.2 Lua演示样例CurrentLanguageTest(当前语言环境) 转载请注明:IT_xiao小巫 本篇博客介绍Cocos2d-x 3.2给我们提供的一个样例.获取当前程 ...

  10. ul、li中的DIV垂直居中

    当li高度可动态改变时,li中的DIV始终保持垂直居中. 由于高度不固定,不能用margin或者padding解决. 最头疼的是vertical-align: middle;也莫名其妙的失效了. 最终 ...