传送:主席树做法http://www.cnblogs.com/candy99/p/6160704.html


做那倒带修改的主席树时就发现分块可以做,然后就试了试

思想和教主的魔法差不多,只不过那个是求>=v的有几个

既然一个数v的名次可以求,我们二分这个数就行了啊

然而......

首先,你二分到的这个数不一定在区间里出现过

比如 1 2 5 8 9

4和5的名次都是3

于是,我修改了某个区间名次的定义:

“如果一个数的名次是x,但是区间中没有次数,那么他的名次为x-1”

实现上只需要find里return l-t+(b[l]==v) 等于说明出现过

然而





该死不写了鬼知道怎么回事用主席树就行了

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. using namespace std;
  7. typedef long long ll;
  8. const int N=1e5+;
  9. inline int read(){
  10. char c=getchar();int x=,f=;
  11. while(c<''||c>''){if(c=='-')f=-; c=getchar();}
  12. while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
  13. return x*f;
  14. }
  15. int n,Q,a[N],bl,m,b[N],pos[N];
  16. int mp[N];
  17. void reset(int x){
  18. int l=(x-)*bl+,r=min(x*bl,n);
  19. for(int i=l;i<=r;i++) b[i]=a[i];
  20. sort(b+l,b+r+);
  21. }
  22. int flag;
  23. int find(int x,int v){
  24. int l=(x-)*bl+,r=min(x*bl,n),t=l;
  25. while(l<=r){
  26. int mid=(l+r)>>;
  27. if(b[mid]<v) l=mid+;
  28. else r=mid-;
  29. }
  30. if(b[l]==v) flag=;
  31. return l-t+;//!
  32. }
  33. int rank(int l,int r,int v){
  34. int ans=;
  35. flag=;
  36. if(pos[l]==pos[r]){
  37. for(int i=l;i<=r;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
  38. }else{
  39. int t=pos[l]*bl;
  40. for(int i=l;i<=t;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
  41. for(int i=(pos[r]-)*bl+;i<=r;i++) if(a[i]<=v) ans++,flag=flag||a[i]==v;
  42. for(int i=pos[l]+;i<pos[r];i++) ans+=find(i,v);
  43. }
  44. if(!flag) ans--;
  45. return ans;
  46. }
  47. int query(int ql,int qr,int k){
  48. int l=,r=n;
  49. while(l<=r){
  50. int mid=(l+r)>>;
  51. int t=rank(ql,qr,mp[mid]);
  52. if(t<k) l=mid+;
  53. else r=mid-;
  54. }
  55. return l;
  56. }
  57. int main(){
  58. freopen("in.txt","r",stdin);
  59. freopen("1.out","w",stdout);
  60. n=read();Q=read();
  61. bl=sqrt(n);
  62. m=n/bl;if(n%bl) m++;
  63. for(int i=;i<=n;i++) a[i]=mp[i]=read(),pos[i]=(i-)/bl+;
  64. for(int i=;i<=m;i++) reset(i);
  65. sort(mp+,mp++n);
  66. while(Q--){
  67. int i=read(),j=read(),k=read();
  68. printf("%d\n",mp[query(i,j,k)]);
  69. }
  70. }
  1. #include <map>
  2. #include <set>
  3. #include <stack>
  4. #include <queue>
  5. #include <cmath>
  6. #include <string>
  7. #include <vector>
  8. #include <cstdio>
  9. #include <cctype>
  10. #include <cstring>
  11. #include <sstream>
  12. #include <cstdlib>
  13. #include <iostream>
  14. #include <algorithm>
  15. #pragma comment(linker,"/STACK:102400000,102400000")
  16.  
  17. using namespace std;
  18. #define MAX 100005
  19. #define MAXN 1000005
  20. #define maxnode 15
  21. #define sigma_size 30
  22. #define lson l,m,rt<<1
  23. #define rson m+1,r,rt<<1|1
  24. #define lrt rt<<1
  25. #define rrt rt<<1|1
  26. #define middle int m=(r+l)>>1
  27. #define LL long long
  28. #define ull unsigned long long
  29. #define mem(x,v) memset(x,v,sizeof(x))
  30. #define lowbit(x) (x&-x)
  31. #define pii pair<int,int>
  32. #define bits(a) __builtin_popcount(a)
  33. #define mk make_pair
  34. #define limit 10000
  35.  
  36. //const int prime = 999983;
  37. const int INF = 0x3f3f3f3f;
  38. const LL INFF = 0x3f3f;
  39. const double pi = acos(-1.0);
  40. const double inf = 1e18;
  41. const double eps = 1e-;
  42. const LL mod = 1e9+;
  43. const ull mx = ;
  44.  
  45. /*****************************************************/
  46. inline void RI(int &x) {
  47. char c;
  48. while((c=getchar())<'' || c>'');
  49. x=c-'';
  50. while((c=getchar())>='' && c<='') x=(x<<)+(x<<)+c-'';
  51. }
  52. /*****************************************************/
  53.  
  54. int a[MAX];
  55. int b[MAX];
  56. int c[MAX];
  57. int tmp;
  58. bool judge(int x,int l,int r,int k){
  59. int a1=l/tmp;
  60. int a2=r/tmp;
  61. int sum=;//for(int i=l;i<=r;i++) printf("%d ",a[i]);puts("");
  62. if(a1==a2){
  63. for(int i=l;i<=r;i++) if(a[i]<=c[x]) sum++;
  64. if(sum>=k) return true;
  65. return false;
  66. }
  67. for(int i=a1+;i<a2;i++){
  68. sum+=upper_bound(b+i*tmp,b+(i+)*tmp,c[x])-b-i*tmp;
  69. }
  70. for(int i=l;i<(a1+)*tmp;i++) if(a[i]<=c[x]) sum++;
  71. for(int i=a2*tmp;i<=r;i++) if(a[i]<=c[x]) sum++;
  72.  
  73. //printf("ra %d %d %d %d\n",l,r,c[x],sum);
  74. if(sum>=k) return true;
  75. return false;
  76. }
  77.  
  78. int main(){
  79. freopen("in.txt","r",stdin);
  80. freopen("2.out","w",stdout);
  81. int n,m;
  82. scanf("%d%d",&n,&m);
  83. tmp=sqrt(n);
  84. for(int i=;i<n;i++){
  85. scanf("%d",&a[i]);
  86. b[i]=a[i];
  87. c[i]=a[i];
  88. }
  89. sort(c,c+n);
  90. for(int i=;i*tmp<n;i++){
  91. if((i+)*tmp<=n) sort(b+i*tmp,b+(i+)*tmp);
  92. else sort(b+i*tmp,b+n);
  93. }
  94. while(m--){
  95. int l,r,k;
  96. scanf("%d%d%d",&l,&r,&k);
  97. int ll=,rr=n-;
  98. while(ll<=rr){
  99. int mid=(ll+rr)>>;
  100. if(judge(mid,l-,r-,k)) rr=mid-;
  101. else ll=mid+;
  102. }
  103. printf("%d\n",c[ll]);
  104. }
  105. return ;
  106. }

别人的AC代码

POJ2104 K-th Number [分块做法]的更多相关文章

  1. [POJ2104] K – th Number (可持久化线段树 主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

  2. ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  3. 【POJ2104】K-th Number

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABToAAAJ2CAIAAADwi6oDAAAgAElEQVR4nOy9a5Pj1nnvi0/Q71Llj3

  4. C++之路进阶——poj2104(K-th Number)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44537   Accepted: 14781 Ca ...

  5. luo3372线段树模板的分块做法

    题目大意 请你维护一个有n个元素的整数序列,要求支持区间查询&区间修改 对于100%的数据,\(1<=n<=10^5\) 分析 正常做法是线段树维护区间修改.区间查询,今天我要讲的 ...

  6. 【poj2104】K-th Number 主席树

    题目描述 You are working for Macrohard company in data structures department. After failing your previou ...

  7. 【POJ2104】K-th Number(主席树)

    题意:有n个数组成的序列,要求维护数据结构支持在线的下列两种操作: 1:单点修改,将第x个数修改成y 2:区间查询,询问从第x个数到第y个之间第K大的数 n<=100000,a[i]<=1 ...

  8. HDU 4366 Successor 分块做法

    http://acm.hdu.edu.cn/showproblem.php?pid=4366 今日重新做了这题的分块,果然是隔太久了,都忘记了.. 首先,用DFS序变成一维的问题 关键是它有两个权值, ...

  9. 「BZOJ3065」带插入区间K小值 [分块]

    考虑分块,每个块都是用 链表 维护的,并保证 \(size\) 和分块相当. 我们考虑一下怎么去查询,很显然,可以对值域分块,单点修改,记录前缀和,完全ojbk了,对每个块维护一个 \(pre , p ...

随机推荐

  1. C#多线程之基础篇2

    在上一篇C#多线程之基础篇1中,我们主要讲述了如何创建线程.中止线程.线程等待以及终止线程的相关知识,在本篇中我们继续讲述有关线程的一些知识. 五.确定线程的状态 在这一节中,我们将讲述如何查看一个线 ...

  2. TCP三次握手的正确使用姿势

    背景 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 问题 有时候聊天的过程中,我的网络或者她的网络可能会不好,视频就会卡住,听不到对方的声 ...

  3. 现代3D图形编程学习-关于本书(译)

    本书系列 现代3D图形编程学习 关于这本书 三维图像处理硬件很快成为了必不可少的组件.很多操作系统能够直接使用三维图像硬件,有些甚至要求需要有3D渲染能力的硬件.同时对于日益增加的手机系统,3D图像硬 ...

  4. Signalr系列之虚拟目录详解与应用中的CDN加速实战

    目录 对SignalR不了解的人可以直接移步下面的目录 SignalR系列目录 前言 前段时间一直有人问我 在用SignalR 2.0开发客服系统[系列1:实现群发通讯]这篇文章中的"/Si ...

  5. ASP.NET Core 中文文档 第一章 入门

    原文:Getting Started 翻译:娄宇(Lyrics) 校对:刘怡(AlexLEWIS) 1.安装 .NET Core 2.创建一个新的 .NET Core 项目: mkdir aspnet ...

  6. jQuery中怎样阻止后绑定事件

    你的代码在页面载入过程中已经完成事件绑定了,没有阻止后绑定的事件的办法了,不过可以删除当前指定节点的事件绑定.方法如下:$("#btn").click(function(){if( ...

  7. Linux网络相关配置

    一.修改网卡相关配置 Linux网络参数是在/etc/sysconfig/network-scripts/ifcfg-eth0中设置,其中ifcfg-eth0表示是第一个网卡,如果还有另外一块网卡,则 ...

  8. UML类图几种关系的总结

    在UML类图中,常见的有以下几种关系: 泛化(Generalization),  实现(Realization),关联(Association),聚合(Aggregation),组合(Composit ...

  9. C#——字段和属性

    //我的C#是跟着猛哥(刘铁猛)(算是我的正式老师)<C#语言入门详解>学习的,微信上猛哥也给我讲解了一些不懂得地方,对于我来说简直是一笔巨额财富,难得良师! 在刚开始学习属性这一节时,开 ...

  10. jquery禁用下拉框

    禁用下拉框 //下拉框禁用 $("select").each(function () { $("#" + this.id).attr("disable ...