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...)
  1. // It is made by XZZ
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<vector>
  5. using namespace std;
  6. #define rep(a,b,c) for(rg int a=b;a<=c;a++)
  7. #define drep(a,b,c) for(rg int a=b;a>=c;a--)
  8. #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
  9. #define il inline
  10. #define rg register
  11. #define vd void
  12. typedef long long ll;
  13. il int gi(){
  14. rg int x=,f=;rg char ch=getchar();
  15. while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
  16. while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
  17. return x*f;
  18. }
  19. vector<int>A;
  20. int main(){
  21. int n=gi(),opt,x;
  22. while(n--){
  23. opt=gi(),x=gi();
  24. if(opt==)A.insert(upper_bound(A.begin(),A.end(),x),x);
  25. else if(opt==)A.erase(lower_bound(A.begin(),A.end(),x));
  26. else if(opt==)printf("%d\n",lower_bound(A.begin(),A.end(),x)-A.begin()+);
  27. else if(opt==)printf("%d\n",A[x-]);
  28. else if(opt==)printf("%d\n",*(lower_bound(A.begin(),A.end(),x)-));
  29. else printf("%d\n",*upper_bound(A.begin(),A.end(),x));
  30. }
  31. return ;
  32. }

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

更新:

液我A了!!!

先上代码

  1. // It is made by XZZ
  2. #include<cstdio>
  3. using namespace std;
  4. #define rep(a,b,c) for(rg int a=b;a<=c;a++)
  5. #define drep(a,b,c) for(rg int a=b;a>=c;a--)
  6. #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
  7. #define il inline
  8. #define rg register
  9. #define vd void
  10. #define Ls tree[now].ls
  11. #define Rs tree[now].rs
  12. typedef long long ll;
  13. il int gi(){
  14. rg int x=,f=;rg char ch=getchar();
  15. while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
  16. while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
  17. return x*f;
  18. }
  19. struct node{
  20. int ls,rs,value,rand,sum,size;
  21. node(){ls=rs=value=rand=sum=size=;}
  22. }tree[];
  23. int root=,siz=;
  24. ll seed=;
  25. il int Rand(){return seed=seed*48271LL%;}
  26. il vd reset(int now){
  27. tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
  28. }
  29. il vd lrot(int&now){
  30. int ls=tree[now].ls;
  31. tree[now].ls=tree[ls].rs,tree[ls].rs=now;
  32. tree[ls].size=tree[now].size;reset(now);now=ls;
  33. }
  34. il vd rrot(int&now){
  35. int rs=tree[now].rs;
  36. tree[now].rs=tree[rs].ls,tree[rs].ls=now;
  37. tree[rs].size=tree[now].size;reset(now);now=rs;
  38. }
  39. il vd ins(int&now,int num){
  40. if(now==){
  41. ++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
  42. return;
  43. }
  44. ++tree[now].size;
  45. if(tree[now].value==num)++tree[now].sum;
  46. else if(num<tree[now].value){
  47. ins(Ls,num);
  48. if(tree[Ls].rand<tree[now].rand)lrot(now);
  49. }else{
  50. ins(Rs,num);
  51. if(tree[Rs].rand<tree[now].rand)rrot(now);
  52. }
  53. }
  54. il vd del(int&now,int num){
  55. if(now==)return;
  56. if(tree[now].value==num){
  57. if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
  58. if(!Ls||!Rs)now=Ls|Rs;
  59. else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
  60. else rrot(now),del(now,num);
  61. return;
  62. }
  63. --tree[now].size;
  64. if(num<tree[now].value)del(Ls,num);
  65. else del(Rs,num);
  66. }
  67. il int getrank(int now,int num){
  68. if(now==)return ;
  69. if(tree[now].value==num)return tree[Ls].size+;
  70. if(num>tree[now].value)return tree[Ls].size+tree[now].sum+getrank(Rs,num);
  71. else return getrank(Ls,num);
  72. }
  73. il int getnum(int now,int num){
  74. if(num<=tree[Ls].size)return getnum(Ls,num);
  75. else if(num>tree[Ls].size+tree[now].sum)return getnum(Rs,num-tree[Ls].size-tree[now].sum);
  76. else return tree[now].value;
  77. }
  78. int ans;
  79. il vd lower(int now,int num){
  80. if(now==)return;
  81. if(tree[now].value<num)ans=now,lower(Rs,num);
  82. else lower(Ls,num);
  83. }
  84. il vd upper(int now,int num){
  85. if(now==)return;
  86. if(tree[now].value>num)ans=now,upper(Ls,num);
  87. else upper(Rs,num);
  88. }
  89. int main(){
  90. int n=gi(),opt,x;
  91. while(n--){
  92. opt=gi(),x=gi();
  93. switch(opt){
  94. case :ins(root,x);break;
  95. case :del(root,x);break;
  96. case :printf("%d\n",getrank(root,x));break;
  97. case :printf("%d\n",getnum(root,x));break;
  98. case :ans=,lower(root,x),printf("%d\n",tree[ans].value);break;
  99. case :ans=,upper(root,x),printf("%d\n",tree[ans].value);break;
  100. }
  101. }
  102. return ;
  103. }
 因为太短了,写一点东西。。。
treap==tree+heap
因为二叉查找树很难平衡,所以加一个随机权值,当作一个堆维护
所以treap既有tree性质又有heap性质
当heap性质被破坏后用旋转来维护
我们还可以把函数写成非递归的。。。
  1. // It is made by XZZ
  2. #include<cstdio>
  3. using namespace std;
  4. #define rep(a,b,c) for(rg int a=b;a<=c;a++)
  5. #define drep(a,b,c) for(rg int a=b;a>=c;a--)
  6. #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
  7. #define il inline
  8. #define rg register
  9. #define vd void
  10. #define Ls tree[now].ls
  11. #define Rs tree[now].rs
  12. typedef long long ll;
  13. il int gi(){
  14. rg int x=,f=;rg char ch=getchar();
  15. while(ch<''||ch>'')f=ch=='-'?-:f,ch=getchar();
  16. while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
  17. return x*f;
  18. }
  19. struct node{
  20. int ls,rs,value,rand,sum,size;
  21. node(){ls=rs=value=rand=sum=size=;}
  22. }tree[];
  23. int root=,siz=;
  24. ll seed=;
  25. il int Rand(){return seed=seed*48271LL%;}
  26. il vd reset(int now){
  27. tree[now].size=tree[Ls].size+tree[Rs].size+tree[now].sum;
  28. }
  29. il vd lrot(int&now){
  30. int ls=tree[now].ls;
  31. tree[now].ls=tree[ls].rs,tree[ls].rs=now;
  32. tree[ls].size=tree[now].size;reset(now);now=ls;
  33. }
  34. il vd rrot(int&now){
  35. int rs=tree[now].rs;
  36. tree[now].rs=tree[rs].ls,tree[rs].ls=now;
  37. tree[rs].size=tree[now].size;reset(now);now=rs;
  38. }
  39. il vd ins(int&now,int num){
  40. if(now==){
  41. ++siz,now=siz,tree[now].size=tree[now].sum=,tree[now].value=num,tree[now].rand=Rand();
  42. return;
  43. }
  44. ++tree[now].size;
  45. if(tree[now].value==num)++tree[now].sum;
  46. else if(num<tree[now].value){
  47. ins(Ls,num);
  48. if(tree[Ls].rand<tree[now].rand)lrot(now);
  49. }else{
  50. ins(Rs,num);
  51. if(tree[Rs].rand<tree[now].rand)rrot(now);
  52. }
  53. }
  54. il vd del(int&now,int num){
  55. if(now==)return;
  56. if(tree[now].value==num){
  57. if(tree[now].sum>){--tree[now].sum,--tree[now].size;return;}
  58. if(!Ls||!Rs)now=Ls|Rs;
  59. else if(tree[Ls].rand<tree[Rs].rand)lrot(now),del(now,num);
  60. else rrot(now),del(now,num);
  61. return;
  62. }
  63. --tree[now].size;
  64. if(num<tree[now].value)del(Ls,num);
  65. else del(Rs,num);
  66. }
  67. il int getrank(int now,int num){
  68. int Rank=;
  69. while(now)if(tree[now].value==num)return tree[Ls].size++Rank;
  70. else if(num>tree[now].value)Rank+=tree[Ls].size+tree[now].sum,now=Rs;
  71. else now=Ls;
  72. }
  73. il int getnum(int now,int num){
  74. while()
  75. if(num<=tree[Ls].size)now=Ls;
  76. else if(num>tree[Ls].size+tree[now].sum)num-=tree[Ls].size+tree[now].sum,now=Rs;
  77. else return tree[now].value;
  78. }
  79. il int lower(int now,int num){
  80. int ret;
  81. while(now)if(tree[now].value<num)ret=tree[now].value,now=Rs;
  82. else now=Ls;
  83. return ret;
  84. }
  85. il int upper(int now,int num){
  86. int ret;
  87. while(now)if(tree[now].value>num)ret=tree[now].value,now=Ls;
  88. else now=Rs;
  89. return ret;
  90. }
  91. int main(){
  92. freopen("phs.in","r",stdin);
  93. freopen("phs.out","w",stdout);
  94. int n=gi(),opt,x;
  95. while(n--){
  96. opt=gi(),x=gi();
  97. switch(opt){
  98. case :ins(root,x);break;
  99. case :del(root,x);break;
  100. case :printf("%d\n",getrank(root,x));break;
  101. case :printf("%d\n",getnum(root,x));break;
  102. case :printf("%d\n",lower(root,x));break;
  103. case :printf("%d\n",upper(root,x));break;
  104. }
  105. }
  106. return ;
  107. }

这样在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. 6 spark 存储体系

    6.1 block存储体系 存储体系架构图 6.2 block 信息信息管理器 6.2.2 bock锁的实现 6.3 磁盘block管理 /* * Licensed to the Apache Sof ...

  2. Apollo深度磁盘清理

    摘要 在Apollo的使用过程中,会出现磁盘空间不足的情况,Apollo的官方提供的方法是删除apollo/data/log或者删除apollo/data/bag文件.但是即使删除了这些,磁盘空间并没 ...

  3. 更换php工具箱出现问题 CI框架的问题 【问题解决】

    2018/10/08 09:56:47 [error] 8472#8588: *1 FastCGI sent in stderr: "PHP Warning:  Unknown: open_ ...

  4. NopCommerce学习(1) Caching

    redis教程 http://www.runoob.com/redis/redis-tutorial.html 下载地址:https://github.com/MSOpenTech/redis/rel ...

  5. oracle的sys和system的默认密码

    oracle的sys和system默认密码system默认:manager sys默认:change_on_install使用PL/SQL Plus登录数据库时,system用户使用密码manager ...

  6. C++快速开发样本工程的建立--建立工程

    因为QT建立工程清晰整洁,便于作为样板工程原型.采用QT 5.8.0 64位版本建立工程. 1.建立工程 打开VS2015 新建->新建项目->QT GUI Application -&g ...

  7. Linux各个文件及其含义

    树状目录结构: 以下是对这些目录的解释: /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像 ...

  8. AFNetworking 2.x 的SSL身份认证

    一般来讲如果app用了web service , 我们需要防止数据嗅探来保证数据安全.通常的做法是用ssl来连接以防止数据抓包和嗅探 其实这么做的话还是不够的.我们还需要防止中间人攻击(不明白的自己去 ...

  9. python list内部功能记录

    list.append(obj) 在列表末尾添加新的对象 list.count(obj) 统计某个元素在列表中出现的次数 list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用 ...

  10. 使用Selenium时,如何选择ChromeDriver驱动版本对应Chrome浏览器版本

      ChromeDriver版本 支持的Chrome版本 v2.46 v72-74 v2.45 v71-73 v2.44 v70-72 v2.43 v69-71 v2.42 v68-70 v2.41 ...