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.每个数的数据范围:[-2e9,2e9]

Source

平衡树

STL用法练手题。。。(手动滑稽)

这数据我给满分
(感谢hzwer...)
 // It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
vector<int>A;
int main(){
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
if(opt==)A.insert(upper_bound(A.begin(),A.end(),x),x);
else if(opt==)A.erase(lower_bound(A.begin(),A.end(),x));
else if(opt==)printf("%d\n",lower_bound(A.begin(),A.end(),x)-A.begin()+);
else if(opt==)printf("%d\n",A[x-]);
else if(opt==)printf("%d\n",*(lower_bound(A.begin(),A.end(),x)-));
else printf("%d\n",*upper_bound(A.begin(),A.end(),x));
}
return ;
}

(学习treap中,到时候再发)

更新:

液我A了!!!

先上代码

 // It is made by XZZ
#include<cstdio>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define Ls tree[now].ls
#define Rs tree[now].rs
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
struct node{
int ls,rs,value,rand,sum,size;
node(){ls=rs=value=rand=sum=size=;}
}tree[];
int root=,siz=;
ll seed=;
il int Rand(){return seed=seed*48271LL%;}
il vd reset(int now){
tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
}
il vd lrot(int&now){
int ls=tree[now].ls;
tree[now].ls=tree[ls].rs,tree[ls].rs=now;
tree[ls].size=tree[now].size;reset(now);now=ls;
}
il vd rrot(int&now){
int rs=tree[now].rs;
tree[now].rs=tree[rs].ls,tree[rs].ls=now;
tree[rs].size=tree[now].size;reset(now);now=rs;
}
il vd ins(int&now,int num){
if(now==){
++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
return;
}
++tree[now].size;
if(tree[now].value==num)++tree[now].sum;
else if(num<tree[now].value){
ins(Ls,num);
if(tree[Ls].rand<tree[now].rand)lrot(now);
}else{
ins(Rs,num);
if(tree[Rs].rand<tree[now].rand)rrot(now);
}
}
il vd del(int&now,int num){
if(now==)return;
if(tree[now].value==num){
if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
if(!Ls||!Rs)now=Ls|Rs;
else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
else rrot(now),del(now,num);
return;
}
--tree[now].size;
if(num<tree[now].value)del(Ls,num);
else del(Rs,num);
}
il int getrank(int now,int num){
if(now==)return ;
if(tree[now].value==num)return tree[Ls].size+;
if(num>tree[now].value)return tree[Ls].size+tree[now].sum+getrank(Rs,num);
else return getrank(Ls,num);
}
il int getnum(int now,int num){
if(num<=tree[Ls].size)return getnum(Ls,num);
else if(num>tree[Ls].size+tree[now].sum)return getnum(Rs,num-tree[Ls].size-tree[now].sum);
else return tree[now].value;
}
int ans;
il vd lower(int now,int num){
if(now==)return;
if(tree[now].value<num)ans=now,lower(Rs,num);
else lower(Ls,num);
}
il vd upper(int now,int num){
if(now==)return;
if(tree[now].value>num)ans=now,upper(Ls,num);
else upper(Rs,num);
}
int main(){
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
switch(opt){
case :ins(root,x);break;
case :del(root,x);break;
case :printf("%d\n",getrank(root,x));break;
case :printf("%d\n",getnum(root,x));break;
case :ans=,lower(root,x),printf("%d\n",tree[ans].value);break;
case :ans=,upper(root,x),printf("%d\n",tree[ans].value);break;
}
}
return ;
}
 因为太短了,写一点东西。。。
treap==tree+heap
因为二叉查找树很难平衡,所以加一个随机权值,当作一个堆维护
所以treap既有tree性质又有heap性质
当heap性质被破坏后用旋转来维护
我们还可以把函数写成非递归的。。。
 // It is made by XZZ
#include<cstdio>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define Ls tree[now].ls
#define Rs tree[now].rs
typedef long long ll;
il int gi(){
rg int x=,f=;rg char ch=getchar();
while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
struct node{
int ls,rs,value,rand,sum,size;
node(){ls=rs=value=rand=sum=size=;}
}tree[];
int root=,siz=;
ll seed=;
il int Rand(){return seed=seed*48271LL%;}
il vd reset(int now){
tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
}
il vd lrot(int&now){
int ls=tree[now].ls;
tree[now].ls=tree[ls].rs,tree[ls].rs=now;
tree[ls].size=tree[now].size;reset(now);now=ls;
}
il vd rrot(int&now){
int rs=tree[now].rs;
tree[now].rs=tree[rs].ls,tree[rs].ls=now;
tree[rs].size=tree[now].size;reset(now);now=rs;
}
il vd ins(int&now,int num){
if(now==){
++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
return;
}
++tree[now].size;
if(tree[now].value==num)++tree[now].sum;
else if(num<tree[now].value){
ins(Ls,num);
if(tree[Ls].rand<tree[now].rand)lrot(now);
}else{
ins(Rs,num);
if(tree[Rs].rand<tree[now].rand)rrot(now);
}
}
il vd del(int&now,int num){
if(now==)return;
if(tree[now].value==num){
if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
if(!Ls||!Rs)now=Ls|Rs;
else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
else rrot(now),del(now,num);
return;
}
--tree[now].size;
if(num<tree[now].value)del(Ls,num);
else del(Rs,num);
}
il int getrank(int now,int num){
int Rank=;
while(now)if(tree[now].value==num)return tree[Ls].size++Rank;
else if(num>tree[now].value)Rank+=tree[Ls].size+tree[now].sum,now=Rs;
else now=Ls;
}
il int getnum(int now,int num){
while()
if(num<=tree[Ls].size)now=Ls;
else if(num>tree[Ls].size+tree[now].sum)num-=tree[Ls].size+tree[now].sum,now=Rs;
else return tree[now].value;
}
il int lower(int now,int num){
int ret;
while(now)if(tree[now].value<num)ret=tree[now].value,now=Rs;
else now=Ls;
return ret;
}
il int upper(int now,int num){
int ret;
while(now)if(tree[now].value>num)ret=tree[now].value,now=Ls;
else now=Rs;
return ret;
}
int main(){
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
int n=gi(),opt,x;
while(n--){
opt=gi(),x=gi();
switch(opt){
case :ins(root,x);break;
case :del(root,x);break;
case :printf("%d\n",getrank(root,x));break;
case :printf("%d\n",getnum(root,x));break;
case :printf("%d\n",lower(root,x));break;
case :printf("%d\n",upper(root,x));break;
}
}
return ;
}

这样在cogs上可以从1.90s下降到1.70s

在洛谷上可以从164ms上升到259ms(大雾)

在bzoj上可以从300ms下降到296ms

所以非递归到底有没有用???

(treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树的更多相关文章

  1. 【替罪羊树】bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树

    [替罪羊树]bzoj3224&luogu3369&cogs1829 [Tyvj 1728]普通平衡树 bzoj 洛谷 cogs 先长点芝士 替罪羊树也是一种很好写的平衡树qwq..替罪 ...

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

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

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

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

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

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

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

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

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

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

  7. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

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

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

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

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

随机推荐

  1. POJ2720 Last Digits

    嘟嘟嘟 一道题又写了近两个点-- 这道题直接暴力快速幂肯定会爆(别想高精),所以还是要用一点数学知识的- 有一个东西叫欧拉降幂公式,就是:      \(x ^ y \equiv x ^ {y \ \ ...

  2. yii2.0 rules 规则中场景验证字段

    除了app场景以外的其他场景都验证uid字段['uid', 'required','except'=>'app', 'message' => '参数错误'], 只有app场景验证uid字段 ...

  3. 自定义ViewPagerIndicator-视图指示器

    ViewPagerIndicator.java public class ViewPagerIndicator extends LinearLayout { private Paint mPaint; ...

  4. @PostConstruct与@PreDestroy讲解及实例

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化后和销毁bean之前进行的操作 第 ...

  5. html5物理定位误差大 解决办法

    学生党在做比赛作品,项目中需求要用到定位功能并以地图形式展现.所以思路就是用h5的geolocation 获取经纬度,通过百度地图api将经纬度转换成详细的地址以及地图.在笔记本电脑做测试,定位总有超 ...

  6. 结构体 内存对齐 keil & STM32

    直接 上图 不废话: 第二张图:  把16位 类型的数据 换成 数组 ,这样 达到 节约内存和  方便处理  缓冲区数据

  7. JavaScript获取0-100之间的随机数

    function (min, max) { return Math.floor(Math.random() * (max - min)) + min } 如果想获取0-100之间的随机数,则可将函数的 ...

  8. python实现用户登录问候

    创建一个至少包含 5个用户名的列表,且其中一个用户名为 'admin' .想象你要编写代码,在每位用户登录网站后都打印一条问候消息.遍历用户名列表,并向每位用户打印一条问候消息.添加一条 if 语句, ...

  9. 使用babel

    1).Babel支持NPM包形式的安装,打开命令行窗口,切换到项目根目录,命令如下 npm install babel-cli 2).安装成功后,在package.json文件里添加如下代码 &quo ...

  10. 由object元素引出的事件注册问题和层级显示问题

    项目有一个双击监控视频全屏的需求,视频播放使用的是IE下的ActiveX控件,web页面中使用HTML嵌入对象元素object.预期方案如下: 1.在开发ActiveX控件时加入双击事件. 2.通过d ...