3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 5354  Solved: 2196
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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]

【思路】

Rank tree

Treap实现名次树。需要多维护s,w域分别表示节点数目与相同键值的数目,相应修改maintain,remove和rank操作。

需要注意的是不能单单在insert的时候安排相同结点放在右子,因为有可能结点通过旋转转上来,这就违反了我们的初衷。

【代码】

 #include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; struct Node{
Node* ch[];
int v,r,s,w;
Node(int x):v(x) { ch[]=ch[]=NULL; s=w=; r=rand(); }
void maintain() {
s=w; //change
if(ch[]!=NULL) s+=ch[]->s;
if(ch[]!=NULL) s+=ch[]->s;
}
int cmp(int x) const {
if(x==v) return -; return x<v?:;
}
};
void rotate(Node* &o,int d) {
Node* k=o->ch[d^]; o->ch[d^]=k->ch[d]; k->ch[d]=o;
o->maintain(); k->maintain(); o=k;
}
//不能只是把大于等于x的放在右子树 有可能旋上来
void insert(Node* &o,int x) {
if(o==NULL) o=new Node(x);
else {
int d=o->cmp(x);
if(d==-) { o->w++; o->maintain(); return; } //相同键值的个数
insert(o->ch[d],x);
if(o->ch[d]->r > o->r) rotate(o,d^);
}
o->maintain();
}
void remove(Node* &o,int x){
if(o==NULL) return ;
int d=o->cmp(x);
if(d==-) {
Node* u=o;
if(o->w>) { o->w--; o->maintain(); return ; } //change2
if(o->ch[]!=NULL && o->ch[]!=NULL) {
int d2=o->ch[]->r > o->ch[]->r? :;
rotate(o,d2); remove(o->ch[d2],x);
}
else {
if(o->ch[]!=NULL) o=o->ch[]; else o=o->ch[];
delete u;
}
}
else remove(o->ch[d],x);
if(o!=NULL) o->maintain();
}
int kth(Node* o,int k) {
if(o==NULL || k<= || k>o->s) return ;
int s=o->ch[]==NULL? :o->ch[]->s,w=o->w;
if(s+<=k && k<=s+w) return o->v;
else if(k<=s) return kth(o->ch[],k);
else return kth(o->ch[],k-s-w);
}
int rank(Node* o,int x) {
if(o==NULL) return ;
int d=o->cmp(x),s=o->ch[]==NULL?:o->ch[]->s;
int f= d==? s+o->w:;
if(d==-) return s+;
else return rank(o->ch[d],x)+f;
}
void query1(Node* o,int x,int& ans) {
if(o==NULL) return ;
if(o->v<x) { ans=o->v; query1(o->ch[],x,ans); }
else query1(o->ch[],x,ans);
}
void query2(Node* o,int x,int& ans) {
if(o==NULL) return ;
if(o->v>x) { ans=o->v; query2(o->ch[],x,ans); }
else query2(o->ch[],x,ans);
}
int n,opt,x,ans;
Node* root=NULL; int main() {
//srand(time(0)); //bzoj上不要用 否则RE
scanf("%d",&n);
FOR(i,,n) {
scanf("%d%d",&opt,&x);
switch(opt) {
case : insert(root,x); break;
case : remove(root,x); break;
case : printf("%d\n",rank(root,x)); break;
case : printf("%d\n",kth(root,x)); break;
case : ans=; query1(root,x,ans); printf("%d\n",ans); break;
case : ans=; query2(root,x,ans); printf("%d\n",ans); break;
}
}
return ;
}

bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)的更多相关文章

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

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

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

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

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

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

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

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

  5. 【权值线段树】bzoj3224 Tyvj 1728 普通平衡树

    一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct ...

  6. 替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树

    冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ). 先是打了一下想学好久的替罪羊树. 替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树. 调试小结: 1.删除操作分两类情况:如果某 ...

  7. BZOJ3224 Tyvj 1728 普通平衡树(Treap)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. 【权值分块】bzoj3224 Tyvj 1728 普通平衡树

    权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...

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

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

随机推荐

  1. Library string type(2)——关于String的操作

    关于string的定义,请参阅博文http://blog.csdn.net/larry233/article/details/51483827 string的操作 s.empty() //Return ...

  2. bzoj3571: [Hnoi2014]画框 最小乘积匹配+最小乘积XX总结,

    思路大概同bzoj2395(传送门:http://www.cnblogs.com/DUXT/p/5739864.html),还是将每一种匹配方案的Σai看成x,Σbi看成y,然后将每种方案转化为平面上 ...

  3. C++学习指南

    转载于stackoverflow:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list 感谢Ge ...

  4. Dynamic Programming: From novice to advanced

    作者:Dumitru 出处:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=dynProg An impo ...

  5. C++写一个排列组合小程序

    今天突然想到一个问题,有时候,针对同一个事件有多种反映,特别是游戏AI当中,这种情况下需要采取最适合的方案,哪种方案最适合,可以将每种方案的结果或影响都计算一遍,从而选择最合适的.最基本就是一个排列组 ...

  6. Ajax--1

    1.Ajax:组合利用javascript.XML和DOM等技术,在无需要刷新页面的前提下实现浏览器与服务器通信.它在用户和服务器之间引入了一个中间层,负责转发用户界面和服务器之间的交互.在服务器处理 ...

  7. WEB架构师成长之路之三-架构师都要懂哪些知识

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  8. 使用ajax传递及接收数据

    前端代码: <input id="txtNum1" name="txtNum1" type="text" width="13 ...

  9. RegexKitLite 使用详解

    1.去RegexKitLite下载类库,解压出来会有一个例子包及2个文件,其实用到的就这2个文件,添加到工程中. 2.工程中添加libicucore.dylib frameworks. 友情提醒:一般 ...

  10. delphi xe5 android 开发数据访问手机端(二)

    界面就这样吧,继续...,先启动咱们上几片文章建立的手机服务端 导入webservices单元,file->new->other->webservices->选择 wsdlim ...