大名鼎鼎的板子题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. Vue-cli 记录

    出自http://www.cnblogs.com/nutritious/p/6494479.html 先给出能正确安装的步骤: 1.进盘符 2,为啥不用npm,这是国外的东西,有些电脑无法FQ,会导致 ...

  2. SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)

    1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地 ...

  3. Volley源码分析一

    Volley源码分析 虽然在2017年,volley已经是一个逐渐被淘汰的框架,但其代码短小精悍,网络架构设计巧妙,还是有很多值得学习的地方. 第一篇文章,分析了请求队列的代码,请求队列也是我们使用V ...

  4. swiper结合ajax的轮播图

    Swiper 是什么:是纯JavaScript打造的滑动特效插件,能够实现触屏焦点图.触屏tab切换.触屏多图切换等常用效果. 开源.免费.稳定.应用广泛. 这就是swiper简单的介绍,由于是结合a ...

  5. Android Studio开发环境配置(win7)

    由于近期,google网站封锁,导致eclipse配置android环境时,无法在线更新API和配置ADT.个人尝试之后,发现很多地方配置因为版本不合适而配置不成功,(ps:当然你FQ,或者下载到对应 ...

  6. C++ 安全单例模式总结

    前两天,一个C++ 的单例实现又掉坑里了.做好一个安全的单例模式可并不简单.这里总结一下C++ 的几个单例实现方案. 1. 函数静态变量法 利用单例函数的静态变量,实现单例构造.代码如下: class ...

  7. css3特效详解

    好吧,CSS3 3D transform变换,不过如此! 这篇文章发布于 2012年09月7日,星期五,01:05,归类于 css相关. 阅读 408042 次, 今日 34 次 一.写在前面的秋裤 ...

  8. mysql查看数据表索引信息

    查看索引 mysql> show index from tblname; mysql> show keys from tblname; · Table 表的名称. · Non_unique ...

  9. 手把手教你 基础 整合最优雅SSM框架:SpringMVC + Spring

    我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...

  10. USACO hamming

    考试周终于过去了一半,可以继续写USACO了. 先来看一下题目吧. Hamming CodesRob Kolstad Given N, B, and D: Find a set of N codewo ...