大名鼎鼎的板子题w

照例先贴题面

Describtion

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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]
此时无声胜有声【大雾
这种时候应该选择直接贴袋马w
后续可能会更新不同做法QwQ
目前为止只用带旋Treap A掉这题感觉我好菜啊w
教练我想学Splay我想学无旋Treap我想学SBT我想学替罪羊QwQ
还要AVL RBT vEBT (教练:我就不信你能学得了这么多还不滚回去打字符串去)
UPD:Splay Tree成功AC
GitHub:
Backup:
 #include <ctime>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std; const int INF=0x7FFFFFFF;
#define lch chd[0]
#define rch chd[1]
#define kch chd[k]
#define xch chd[k^1] class Treap{
private:
int v;
int k;
int s;
public:
Treap* chd[];
Treap(int v=,Treap* l=NULL,Treap* r=NULL,int s=,int k=rand()){
this->v=v;
this->s=s;
this->k=k;
this->chd[]=l;
this->chd[]=r;
}
inline void Maintain(){
if(this->exist())
this->s=this->lch->size()+this->rch->size()+;
}
inline int value(){
return this==NULL?:v;
}
inline int key(){
return this==NULL?INF:k;
}
inline int size(){
return this==NULL?:s;
}
inline bool empty(){
return this==NULL;
}
inline bool exist(){
return this!=NULL;
}
}*Root=NULL; void Insert(Treap*&,int);
void Delete(Treap*&,int);
void Rotate(Treap*&,int);
int Rank(int);
int Kth(int);
int Predecessor(int);
int Successor(int); inline void PrintTree(){
queue<Treap*> q;
q.push(Root);
while(!q.empty()){
if(q.front()->empty()){
puts("(v=@@@,s=@@@,k=@@@)");
}
else{
printf("(v=%d,s=%d,k=%d)\n",q.front()->value(),q.front()->size(),q.front()->key());
q.push(q.front()->lch);
q.push(q.front()->rch);
}
q.pop();
}
printf("\n\n\n\n");
} int main(){
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
srand(time(NULL));
int n,type,num;
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&type,&num);
if(type==)
Insert(Root,num);
else if(type==)
Delete(Root,num);
else if(type==)
printf("%d\n",Rank(num));
else if(type==)
printf("%d\n",Kth(num));
else if(type==)
printf("%d\n",Predecessor(num));
else if(type==)
printf("%d\n",Successor(num));
// PrintTree();
}
return ;
} void Insert(Treap* &root,int x){
if(root->empty()){
root=new Treap(x);
return;
}
else{
int k=x<root->value();
Insert(root->xch,x);
root->Maintain();
if(root->xch->key()>root->key())
Rotate(root,k);
}
} void Delete(Treap* &root,int x){
if(root->empty())
return;
else{
if(root->value()==x){
if(root->lch->exist()&&root->rch->exist()){
int k=root->lch->key()>root->rch->key();
Rotate(root,k);
Delete(root->kch,x);
}
else{
Treap* tmp=root;
if(root->lch->exist())
root=root->lch;
else
root=root->rch;
delete tmp;
}
}
else
Delete(root->chd[x>=root->value()],x);
root->Maintain();
}
} inline int Rank(int x){
Treap* root=Root;
int ans=;
while(root->exist()){
if(x<=root->value())
root=root->lch;
else{
ans+=root->lch->size()+;
root=root->rch;
}
}
return ans;
} inline int Kth(int x){
Treap* root=Root;
int k;
while(root->exist()){
k=root->lch->size()+;
if(x<k)
root=root->lch;
else if(x==k)
return root->value();
else{
x-=k;
root=root->rch;
}
}
return ;
} inline int Predecessor(int x){
return Kth(Rank(x)-);
} inline int Successor(int x){
return Kth(Rank(x+));
} inline void Rotate(Treap* &root,int k){
Treap* tmp=root->xch;
root->xch=tmp->kch;
root->Maintain();
tmp->kch=root;
tmp->Maintain();
root=tmp;
}

Treap

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #define lch chd[0]
#define rch chd[1]
#define kch chd[k]
#define xch chd[k^1] const int INF=0x7FFFFFFF; class SplayTree{
private:
struct Node{
int k;
int s;
Node* prt;
Node* chd[];
Node(const int& key){
this->k=key;
this->s=;
this->prt=NULL;
this->lch=NULL;
this->rch=NULL;
}
inline int size(){
return this==NULL?:this->s;
}
inline int key(){
return this==NULL?:this->k;
}
inline void Maintain(){
if(this!=NULL)
this->s=this->lch->size()+this->rch->size()+;
}
inline int Pos(){
return this==this->prt->lch;
}
}*root; void Rotate(Node* root,int k){
Node* tmp=root->xch;
if(root->prt==NULL)
this->root=tmp;
else if(root->prt->lch==root)
root->prt->lch=tmp;
else
root->prt->rch=tmp;
tmp->prt=root->prt;
root->xch=tmp->kch;
if(root->xch!=NULL)
root->xch->prt=root;
tmp->kch=root;
root->prt=tmp;
root->Maintain();
tmp->Maintain();
} void Splay(Node* root,Node* prt=NULL){
while(root->prt!=prt){
int k=root->Pos();
if(root->prt->prt==prt){
this->Rotate(root->prt,k);
}
else{
int d=root->prt->Pos();
this->Rotate(k==d?root->prt->prt:root->prt,k);
this->Rotate(root->prt,d);
}
}
}
public:
Node* Kth(int pos){
Node* root=this->root;
while(root!=NULL){
int k=root->lch->size()+;
if(pos<k)
root=root->lch;
else if(pos==k)
return root;
else{
pos-=k;
root=root->rch;
}
}
return NULL;
} int Rank(const int& key){
Node* root=this->root;
int rank=;
while(root!=NULL){
if(root->key()<key){
rank+=root->lch->size()+;
root=root->rch;
}
else
root=root->lch;
}
return rank;
} void Insert(const int& key){
int pos=this->Rank(key)-;
this->Splay(this->Kth(pos));
this->Splay(this->Kth(pos+),this->root);
Node* tmp=new Node(key);
this->root->rch->lch=tmp;
tmp->prt=this->root->rch;
this->root->rch->Maintain();
this->root->Maintain();
} void Delete(const int& key){
int pos=this->Rank(key);
this->Splay(this->Kth(pos-));
this->Splay(this->Kth(pos+),root);
delete this->root->rch->lch;
this->root->rch->lch=NULL;
this->root->rch->Maintain();
this->root->Maintain();
} inline int Predecessor(const int& key){
return this->Kth(this->Rank(key)-)->key();
} inline int Successor(const int& key){
return this->Kth(this->Rank(key+))->key();
} SplayTree(){
this->root=new Node(-INF);
this->root->rch=new Node(INF);
this->root->rch->prt=this->root;
this->root->rch->Maintain();
this->root->Maintain();
}
}; int main(){
#ifndef ASC_LOCAL
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
#endif
SplayTree* T=new SplayTree();
int t,opt,key;
scanf("%d",&t);
while(t--){
scanf("%d%d",&opt,&key);
if(opt==)
T->Insert(key);
else if(opt==)
T->Delete(key);
else if(opt==)
printf("%d\n",T->Rank(key)-);
else if(opt==)
printf("%d\n",T->Kth(key+)->key());
else if(opt==)
printf("%d\n",T->Predecessor(key));
else
printf("%d\n",T->Successor(key));
}
return ;
}

Splay

[Tyvj 1728] 普通平衡树的更多相关文章

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

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

  2. BZOJ 3224: Tyvj 1728 普通平衡树

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

  3. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  4. BZOJ 3224: Tyvj 1728 普通平衡树 treap

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

  5. BZOJ 3224: Tyvj 1728 普通平衡树 vector

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

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

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

  7. BZOJ 3224: Tyvj 1728 普通平衡树(BST)

    treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...

  8. [补档][Tyvj 1728]普通平衡树

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

  9. 【bzoj】3224: Tyvj 1728 普通平衡树

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

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

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

随机推荐

  1. fetch()的用法

    发起获取资源请求的我们一般都会用AJAX技术,最近在学习微信小程序的时候,用到了fetch()方法. fetch()方法用于发起获取资源的请求.它返回一个promise,这个promise会在请求响应 ...

  2. 对jsp的初步了解及规范问题(二)

    前言 今天的例子是用jsp制作简单的“艾宾浩斯记忆曲线的学习计划表”. 重点不是算法,重点是学习jsp中的一个重要的思想,作为展现层,jsp中不应该出现业务逻辑代码. 当中<%%>代码也会 ...

  3. 在64位Ubuntu系统上安装32位程序包

    在64位Ubuntu系统上安装32位的程序包 $sudo apt-get install package_name:i386 例如: $sudo apt-get install openjdk-7-j ...

  4. jquery 实现滚动条下拉时无限加载的简单实例

    var lastId=0;//记录每一次加载时的最后一条记录id,跟您的排序方式有关.     var isloading = false;   $(window).bind("scroll ...

  5. 【Python3之基本数据类型,基本运算】

    一.基本数据类型 1.字符串 类:str 方法:选中str,按住command(ctrl)+左键跳转至对应的方法 创建 a = "hexin" a = str('hexin') 转 ...

  6. AngularJS高级程序设计读书笔记 -- 指令篇 之 自定义指令

    2. 自定义指令(15-17 章) Module.directive(name, factory) 2.1 创建自定义指令的方法 Module.directive(name, factory) 示例 ...

  7. 微信小程序开发过程中一些经验总结

    1.微信开发者工具报错,微信小程序最低需支持tls1.2版本的问题 原因是服务器不支持ssl的高版本,解决方法: 在/etc/nginx/conf.d文件下,把"ssl_protocols  ...

  8. linux下安装apache最常见的报错解决

    报错如下: Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, ...

  9. 【Android Developers Training】 52. 打印照片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  10. 5.Smart使用内置函数或者自定义函数

    1.使用内置函数 例如使用date函数 {"Y-m-d"|date:$time}格式{第一个参数|方法:第二个参数:第三个参数}即可转换成 2016-07-19  2.使用resi ...