洛谷 P3369 【模板】普通平衡树(Treap/SBT)
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
- 插入x数
- 删除x数(若有多个相同的数,因只删除一个)
- 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
- 查询排名为x的数
- 求x的前驱(前驱定义为小于x,且最大的数)
- 求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1≤opt≤6)
输出格式:
对于操作3,4,5,6每行输出一个数,表示对应答案
输入输出样例
输入样例:
输出样例:
Splay 解析尚未完成 参见yyb dalao的博客
丑陋的代码送上(yyb大佬的代码比我的漂亮多了):
#ifndef SPLAY_TREE_HPP
#define SPLAY_TREE_HPP
#include<bits/stdc++.h>
using namespace std;
namespace Splay_tree
{
template<typename T>
struct splay_node
{
T value;
int size;
int cnt;
bool reverse;
splay_node *father;
splay_node *son[];
splay_node(){}
splay_node(T v, splay_node *f=NULL)
:value(v),cnt()
{
father=f;
size=;
son[]=son[]=NULL;
}
}; template<typename T, typename C=less<T> >
class Splay
{
private:
typedef splay_node<T> node;
node *root;
C small_to;
bool big_to(T x, T y){return small_to(y,x);}
bool equal_to(T x, T y){return !(small_to(x,y)||big_to(x,y));} inline bool son(node *f, node *s)
{
return f->son[]==s;
}
inline void rotate(node *t)
{
node *f = t->father;
node *g = f->father;
bool a = son(f, t), b = !a;
f->son[a] = t->son[b];
if (t->son[b] != NULL)
t->son[b]->father = f;
t->son[b] = f;
f->father = t;
t->father = g;
if (g != NULL)
g->son[son(g, f)] = t;
else
root = t;
update(f);
update(t);
} inline void splay(node *t, node *p)
{
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);
}
}
update(t);
} inline T k_th(int k, node *f)
{
int tmp;
node *t=root;
while()
{
int tmp=size(t->son[])+t->cnt;
int sze=tmp-t->cnt;
if(k<=tmp&&sze<k) break;
else if(k<=sze) t=t->son[];
else k-=tmp,t=t->son[];
}
T ans=t->value;
return ans;
} inline node* insert(T val, node *t)
{
int b=big_to(val,t->value);
if(equal_to(val,t->value))
{
t->cnt++;
update(t);
return t;
}
if(t->son[b]==NULL)
{
t->son[b]=new node(val,t);
update(t->son[b]);
update(t);
return t->son[b];
}
else
{
node *ans=insert(val,t->son[b]);
update(t);
return ans;
}
} public:
Splay()
{
root=NULL;
} inline void insert(T val)
{
if (root == NULL)
{
root = new node(val, NULL);
update(root);
return;
}
else
{
node *t = insert(val,root);
splay(t,NULL);
}
} inline void erase(T val)
{
node *t = root;
while(t)
{
if (equal_to(t->value,val))
break;
t = t->son[big_to(val,t->value)];
}
if (t != NULL)
{
splay(t, NULL);
if(t->cnt>)
{
t->cnt--;
update(t);
return;
}
if (t->son[] == NULL)
{
root = t->son[];
if (root != NULL)
{
root->father = NULL;
update(root);
}
}
else
{
node *p = t->son[];
while (p->son[] != NULL)
p = p->son[];
splay(p, t); root = p;
root->father = NULL;
p->son[] = t->son[];
update(p);
if (p->son[] != NULL)
p->son[]->father = p;
}
}
} inline T pre(T val)
{
T ans=pre_ptr(val)->value;
return ans;
} inline T suc(T val)
{
node *x = root;
insert(val);
node *t=root->son[];
if(t==NULL) return T(NULL);
while(t->son[]!=NULL) t=t->son[];
erase(val);
T ans=t->value;
return ans;
} inline T max_value()
{
node *t=root;
while(t->son[]!=NULL) t=t->son[];
return t->value;
} inline T min_value()
{
node *t=root;
while(t->son[]!=NULL) t=t->son[];
return t->value;
} inline T k_th(int k)
{
return k_th(k,NULL);
} inline int rank(T val)
{
node *t=root;
while(!equal_to(t->value, val))
t=t->son[big_to(val,t->value)];
splay(t,NULL);
return size(t->son[])+;
} inline void print()
{
print(root);
puts("");
} private: inline node* pre_ptr(T val)
{
insert(val);
node *t=root->son[];
if(t==NULL) return NULL;
while(t->son[]!=NULL) t=t->son[];
erase(val);
return t;
} inline void print(node *t)
{
if(t==NULL) return;
print(t->son[]);
printf("%d ",t->value);
print(t->son[]);
} inline int size(node *t)
{
return t == NULL ? : t->size;
} inline void update(node *t)
{
t->size = t->cnt;
t->size += size(t->son[]);
t->size += size(t->son[]);
}
};
}
#endif int main()
{
using namespace Splay_tree;
int n;
Splay<int> tree;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int ops;
int x;
scanf("%d%d",&ops,&x);
switch(ops)
{
case :
tree.insert(x);
break;
case :
tree.erase(x);
break;
case :
{
int t=tree.rank(x);
printf("%d\n",t);
break;
}
case :
{
int y=tree.k_th(x);
printf("%d\n",y);
break;
}
case :
printf("%d\n",tree.pre(x));
break;
case :
int t=tree.suc(x);
printf("%d\n",t);
break;
}
}
}
洛谷 P3369 【模板】普通平衡树(Treap/SBT)的更多相关文章
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 洛谷.3369.[模板]普通平衡树(fhq Treap)
题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- 【洛谷P3369】普通平衡树——Splay学习笔记(一)
二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...
- 洛谷.3369.[模板]普通平衡树(Splay)
题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...
- 洛谷.3391.[模板]文艺平衡树(Splay)
题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- 【洛谷P3369】【模板】普通平衡树题解
[洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...
- 洛谷P3369普通平衡树(Treap)
题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369
[模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...
随机推荐
- CF Gym 100637B Lunch(拆分子问题)
题意:在一条狭窄的沼泽上有一列数量为n的连续荷叶,编号为1-n.有一只蛤,在边s号荷叶上,其他荷叶上苍蝇,哈可以跳到相邻的荷叶上,或者越过一片荷叶,跳完以后原来的荷叶会沉,目标是f荷叶,在跳到f荷叶之 ...
- HTTP协议实体的基本讲解
http://blog.csdn.net/diyagoanyhacker/article/details/6685305 HTTP协议运作方式 HTTP协议是基于请求/响应范式的.一个客户机与服务器建 ...
- BZOJ1049:[HAOI2006]数字序列(DP)
Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列. 但是不希望改变过多的数,也不希望改变的幅度太大. Input 第一行包含一个 ...
- 随手练——HDU-2037 、P-2920 时间安排(贪心)
普通时间安排 HDU-2037 :http://acm.hdu.edu.cn/showproblem.php?pid=2037 选取结束时间早的策略. #include <iostream> ...
- 10-RabbitMQ-整合SpringBoot
RabbitMQ整个SpringBoot SpringBoot因其配置简单.快速开发,已经成为热门的开发之一 消息中间件的工作过程可以用生产者消费者模型来表示.即,生产者不断的向消息队列发送信息 而消 ...
- WEB安全 ACCESS 注入、盲注脚本
http://www.xxx.cn/cp.asp?classid=3http://www.xxx.cn/cp.asp?classid=3 and //有拦截关键字http://www.xxx.cn/c ...
- ASP.Net MVC的学习
套种间作,也挺有意思的——近来学习感悟.DRP学习的同时,折腾了点以前不曾学习但是却很多次耳闻过的东西——Asp.Net中的MVC架构模式. 一.是什么? MVC,即(Model-View-Contr ...
- NOIP模拟赛D2T1自己的解题思路
T1题目在此: 数轴上有n个球,每个球直径为1,第 ii 个球的左端点为pi即占据了数轴上[pi,pi+1][pi,pi+1]).在 P位置有一堵墙.有q个操作,每次要么以x位置为左端点放一个新球(如 ...
- #leetcode刷题之路24-两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表.你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例:给定 1->2->3->4, 你应该返回 2-> ...
- C++练习 | 运算符重载练习(字符串相关)
#include <iostream> #include <cmath> #include <cstring> #include <string> #i ...