来自FallDream的博客,未经允许,请勿转载,谢谢。


维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作:

1 k,将序列a从小到大排序,输出a_k的值。
2 k,将所有严格大于k的数a_i减去k。
n,m<=100000
 
splay维护序列,每次操作小等于k的数字不变,大于2k的数字顺序不变,(k,2k]的数字减小至少一半,最多减小log次,暴力拿出来重新插入就行了。
复杂度nlog^2n
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<algorithm>
  5. #define Rint register int
  6. #define ll long long
  7. #define MN 100000
  8. #define INF 1000000000000000000LL
  9. #define getchar() (*S++)
  10. char B[<<],*S=B;
  11. using namespace std;
  12. inline int read()
  13. {
  14. int x = , f = ; char ch = getchar();
  15. while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
  16. while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
  17. return x * f;
  18. }
  19. int c[MN+][],fa[MN+],rt=,tag[MN+],n,m,size[MN+],q[MN+],top=;
  20. ll a[MN+];
  21. inline void update(int x){size[x]=size[c[x][]]+size[c[x][]]+;}
  22. inline void Mark(int x,int v){tag[x]+=v;a[x]+=v;}
  23. inline void pushdown(int x){Mark(c[x][],tag[x]);Mark(c[x][],tag[x]);tag[x]=;}
  24.  
  25. void rotate(int x,int&k)
  26. {
  27. int y=fa[x],z=fa[y],l=c[y][]==x,r=l^;
  28. if(y==k) k=x; else c[z][c[z][]==y]=x;
  29. fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
  30. c[y][l]=c[x][r];c[x][r]=y;
  31. update(y);update(x);
  32. }
  33.  
  34. void Splay(int x,int&k)
  35. {
  36. for(;x!=k;rotate(x,k))
  37. if(fa[x]!=k) rotate((c[fa[fa[x]]][]==fa[x]^c[fa[x]][]==x)?x:fa[x],k);
  38. }
  39.  
  40. void build(int&x,int l,int r,int last)
  41. {
  42. if(l>r) {x=;return;}x=l+r>>;fa[x]=last;
  43. build(c[x][],l,x-,x);
  44. build(c[x][],x+,r,x);
  45. update(x);
  46. }
  47.  
  48. int Ask_After(int x,int v)
  49. {
  50. if(!x) return ;int q;
  51. if(tag[x]) pushdown(x);
  52. if(a[x]>v) return (q=Ask_After(c[x][],v))?q:x;
  53. else return Ask_After(c[x][],v);
  54. }
  55.  
  56. int Ask_Before(int x,int v)
  57. {
  58. if(!x) return ;int q;
  59. if(tag[x]) pushdown(x);
  60. if(a[x]<=v) return (q=Ask_Before(c[x][],v))?q:x;
  61. else return Ask_Before(c[x][],v);
  62. }
  63.  
  64. int Find(int x,int rk)
  65. {
  66. int Sz=size[c[x][]]+;
  67. if(tag[x]) pushdown(x);
  68. if(Sz==rk) return x;
  69. if(Sz<rk) return Find(c[x][],rk-Sz);
  70. else return Find(c[x][],rk);
  71. }
  72.  
  73. void Dfs(int x)
  74. {
  75. if(tag[x]) pushdown(x);
  76. if(c[x][]) Dfs(c[x][]);
  77. q[++top]=x;
  78. if(c[x][]) Dfs(c[x][]);
  79. }
  80.  
  81. void Ins(int&x,int k,int last)
  82. {
  83. if(!x){x=k;c[k][]=c[k][]=;fa[k]=last;size[k]=;return;}
  84. if(tag[x]) pushdown(x);
  85. Ins(c[x][a[k]>=a[x]],k,x);
  86. update(x);
  87. }
  88.  
  89. int main()
  90. {
  91. fread(B,,<<,stdin);
  92. n=read();m=read();
  93. for(Rint i=;i<=n;++i) a[i+]=read();a[]=-INF;a[n+]=INF;
  94. sort(a+,a+n+);build(rt,,n+,);
  95. for(Rint i=;i<=m;++i)
  96. {
  97. int op=read(),v;
  98. if(op==){printf("%d\n",(v=Find(rt,read()+),Splay(v,rt),a[v]));}
  99. if(op==)
  100. {
  101. v=read();int x=Ask_Before(rt,v),y=Ask_After(rt,v<<);
  102. Splay(x,rt);Splay(y,c[rt][]);int z=c[y][];
  103. if(z) {top=;Dfs(z);fa[z]=;c[y][]=;}
  104. update(y);update(x);Mark(y,-v);
  105. if(z) for(Rint j=;j<=top;++j) a[q[j]]-=v,Ins(rt,q[j],),Splay(q[j],rt);
  106. }
  107. }
  108. return ;
  109. }

[bzoj4923]K小值查询的更多相关文章

  1. BZOJ4923 K小值查询(splay)

    容易想到建一棵平衡树,修改时打上标记即可.但是修改会导致平衡树结构被破坏.注意到实际上只有[k+1,2k)这一部分数在平衡树中的位置会被改变,所以对这一部分暴力修改,因为每次都会使其至少减小一半,复杂 ...

  2. [BZ4923][Lydsy1706月赛]K小值查询

    K小值查询 题面 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. Input ...

  3. BZOJ4923:[Lydsy1706月赛]K小值查询(Splay)

    Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...

  4. BZOJ 4923: [Lydsy1706月赛]K小值查询 Splay + 思维

    Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...

  5. BZOJ4923 [Lydsy1706月赛]K小值查询

    题意 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. \(n \leq 10 ...

  6. 4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap

    国际惯例的题面:这种维护排序序列,严格大于的进行操作的题都很套路......我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好.显然第一个区间的不会变化,第二个区间的会被平移进第一个区 ...

  7. [BZOJ 4923][Lydsy1706月赛]K小值查询

    传送门 势能分析平衡树,splay或treap都可以 放个指针版的就跑 #include <bits/stdc++.h> using namespace std; #define rep( ...

  8. 【BZOJ】3065: 带插入区间K小值

    http://www.lydsy.com/JudgeOnline/problem.php?id=3065 题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175 ...

  9. bzoj 3065: 带插入区间K小值 替罪羊树 && AC300

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Des ...

随机推荐

  1. java关于for循环。

    众所周知,JAVA中for循环的基本格式为: for(初始化表达式:布尔表达式:循环后更新表达式){循环体} 举个例子来说可以写成 (1)for (int x=1;x<10;x++){ Syst ...

  2. 为微软samples-for-ai贡献代码是种怎么样的体验?

    推送原文链接:传送门 关注SomedayWill,了解为微软项目贡献代码的始终. 还记得微软神器samples-for-ai吗?它可不仅仅可以用来安装框架,它其实是个开源的AI样例库,以Visual ...

  3. JavaSE阶段初期的一些问题

    ​​​对于如下问题1:编译阶段Demo1会报错,Demo2不会报错. class Demo1{ int i; i = 0; } class Demo2{ int i = 0; } 事实上,在java中 ...

  4. C# 大数组赋值给小数组,小数组赋值给大数组

    ]; ]; " }; arraymax = arraystr;//变成和arraystr一样 arraymin = arraystr;//变成和arraystr一样

  5. 第二章 JavaScript核心语法

    第二章   avaScript核心语法 一.变量的声明和赋值 JavaScript是一种弱类型语言,没有明确的数据类型,也就是在声明变量时不需要指定数据类型,变量的类型由赋给变量的值决定. 在Java ...

  6. vue-cli webpack3扩展多模块打包

    场景 在实际的项目开发中会出现这样的场景,项目中需要多个模块(单页或者多页应用)配合使用的情况,而vue-cli默认只提供了单入口打包,所以就想到对vue-cli进行扩展 实现 首先得知道webpac ...

  7. springboot字符集乱码

    入门扫盲:https://www.2cto.com/database/201701/584442.html 1.修改springweb类bug 2.数据库连接配置 3.数据库字符集 https://w ...

  8. 基于python的统计公报关键数据爬取

    # -*- coding: utf-8 -*- """ Created on Wed Nov 8 14:23:14 2017 @author: 123 "&qu ...

  9. jquery-模仿qq提示消息

    ( function() { var ua = navigator.userAgent.toLowerCase(); var is = (ua.match(/\b(chrome|opera|safar ...

  10. django的models模型 关联关系和关系查询

    模型类关系 关系字段类型 关系型数据库的关系包括三种类型: ForeignKey:一对多,将字段定义在多的一端中. ManyToManyField:多对多,将字段定义在两端中. OneToOneFie ...