原帖:http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html

回顾树状数组的定义,注意到有如下两条性质:
一,c[ans]=sum of A[ans-lowbit(ans)+1 ... ans];
二,当ans=2^k时,
 c[ans]=sum of A[1 ... ans];

下面说明findK(k)如何运作:
1,设置边界条件ans,ans'<maxn且cnt<=k;
2,初始化cnt=c[ans],其中ans=2^k且k为满足边界条件的最大整数;
3,找到满足边界条件的最大的ans'使得ans'-lowbit(ans')=ans,即ans'满足c[ans']=A[ans+1 .. ans'](根据性质一),只要将c[ans']累加到cnt中(此时cnt=sum of A[1 ... ans'],根据性质二),cnt便可以作为k的逼近值;
4,重复第3步直到cnt已无法再逼近k,此时ans刚好比解小1,返回ans+1。

因此findk(k)的实质就是二分逼近

 /**********************************

 树状数组实现查找K小的元素

                   经典。

 限制:数据范围在1<<20 以内

 ***********************************/

 #include <iostream>

 using namespace std;

 #define maxn 1<<20

 int n,k;

 int c[maxn];

 int lowbit(int x){

     return x&-x;

 }

 void insert(int x,int t){

        while(x<maxn){

           c[x]+=t;

           x+=lowbit(x);    

        }

 }

 int find(int k){

     int cnt=,ans=;

     for(int i=;i>=;i--){

         ans+=(<<i);

         if(ans>=maxn || cnt+c[ans]>=k)ans-=(<<i);

         else cnt+=c[ans];

     }

     return ans+;

 }

 void input(){

        memset(c,,sizeof(c));

        int t;

        scanf("%d%d",&n,&k);

        for(int i=;i<n;i++){    

             scanf("%d",&t);

             insert(t,);

        }

        printf("%d\n",find(k));

 }

 int main(){

     int cases;

     scanf("%d",&cases);

     while(cases--){

         input();

     }

     return ;

 }

【转载】【树状数组区间第K大/小】的更多相关文章

  1. Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)

    Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...

  2. HDU 5249 离线树状数组求第k大+离散化

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  3. poj 2985 The k-th Largest Group 树状数组求第K大

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8353   Accepted ...

  4. hdu5592/BestCoder Round #65 树状数组寻找第K大

    ZYB's Premutation    Memory Limit: 131072/131072 K (Java/Others) 问题描述 ZYBZYB有一个排列PP,但他只记得PP中每个前缀区间的逆 ...

  5. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  6. 树状数组求第K大(From CLJ)

    ; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;

  7. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  8. 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

    题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不 ...

  9. 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询

    题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...

随机推荐

  1. HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

    Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. HDU-2149 Public Sale

    http://acm.hdu.edu.cn/showproblem.php?pid=2149 巴什博奕(Bash Game): Public Sale Time Limit: 1000/1000 MS ...

  3. Git error: hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused b

    hint: Updates were rejected because the remote contains work that you dohint: not have locally. This ...

  4. ios新特性

    @import  在xcode 5 下,为了更易于开发,增加了modules和 auto-linking 这两个新特性: 在以前,如果你要使用MapKit这个框架,你要这样做 1) 使用语句 #imp ...

  5. spring security 允许 iframe 嵌套

    spring security +spring boot框架, 允许 嵌套ifram :

  6. Ubuntu开机出现:Fontconfig warning:"/etc/fonts/conf.d/65-droid-sans-fonts.conf"的解决办法

    Ubuntu升级后可能会出现以下问题: Fontconfig warning: "/etc/fonts/conf.d/65-droid-sans-fonts.conf", line ...

  7. Tomcat配置多个端口号或多个应用

    一.在Tomcat下配置一个应用服务(service)中,配置多个端口号. 即一个service配置多个端口,项目可以通过多个端口访问. 修改tomcat-home\conf下的server.xml, ...

  8. 通过WriteProcessMemory改写进程的内存

    http://www.cnblogs.com/feiyucq/archive/2009/10/21/1587628.html 以PROCESS_ALL_ACCESS权限打开进程以后既能够使用ReadP ...

  9. 【Linux学习笔记】用nc实现两台主机间的文件传输(不需要输密码)

    通常,可以用scp完成两台主机间的文件传输任务,但在主机间未建立信任关系的情况下,scp每次都需要输入密码,用起来感觉不是很方便,之前这篇笔记介绍过不用输入密码执行脚本或传输文件的方法,但对于一些临时 ...

  10. java文件处理工具类

    import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedRead ...