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. pip-修改为国内镜像源

    pip 常用命令 pip install ./downloads/SomePackage-1.0.4.tar.gz pip install http://my.package.repo/SomePac ...

  2. [Python 模块] logging模块、Logger类

    logging模块: 标准库里面的logging模块,在前面学习线程安全时曾用来解决print被打断的问题,这里会介绍logging模块的功能. logging模块是线程安全的,不需要客户做任何特殊的 ...

  3. LayIM.AspNetCore Middleware 开发日记(二)预备知识介绍

    前言 开发一个AspNetCore的中间件需要理解RequestDelegate.另外,还需要理解.NET Core中的依赖注入.还有一个就是内嵌资源的访问.例如:EmbeddedFileProvid ...

  4. linux下批量重命名文件

    # 使用通配符批量创建 多个文件:$ touch zqunor{1..7}.txt # 批量将多个后缀为 .txt 的文本文件重命名为以 .c 为后缀的文件:$ rename 's/\.txt/\.c ...

  5. 关于RAM与ROM的区别与理解

    随机存取存储器(random access memory,RAM)又称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存).它可以随时读写,而且速度很快,通常作为操作系统或其他正在运 ...

  6. select和epoll

    C/S编程模型,对每一个客户端都要开辟一个新的线程,效率必定低下.普通select模型是开辟两个线程,一个用来监听客户端的连接,另一个用于处理客户端请求. fd_set set; FD_ZERO(&a ...

  7. Unity-iPhone has Conflicting Provisioning Settings

    Select the top level node called Unity-iPhone in the left tree view (the one with the blue item). Se ...

  8. Xcode官方xip直接离线下载地址(更新到Xcode 9.4.1)

    Xcode 9.4.1 https://download.developer.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip Xcode 9 ...

  9. 替代alert的消息框和提示框

    alert提示框由于外观不太友好,所以一般都不用alert了. 我在这里使用bootstrap的样式,写了一个可以单独显示消息,也可以确认取消的提示框,确认,取消的采用模式对话框方式,用一个div遮盖 ...

  10. My SQL常用操作汇总

    写这篇随笔的目的是我发现了在上一篇关于My SQL的随笔中存在一些不严谨的代码问题,在这里再次简单的总结一下并加以改进,以代码为主. # !每行命令必须以分号(;)结尾 先通过命令行进入数据库客户端 ...