【转载】【树状数组区间第K大/小】
原帖: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大/小】的更多相关文章
- Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- hdu5592/BestCoder Round #65 树状数组寻找第K大
ZYB's Premutation Memory Limit: 131072/131072 K (Java/Others) 问题描述 ZYBZYB有一个排列PP,但他只记得PP中每个前缀区间的逆 ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- 树状数组求第K大(From CLJ)
; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询
题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不 ...
- 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询
题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...
随机推荐
- 【转】Android--多线程之Handler--不错
原文网址:http://www.cnblogs.com/plokmju/p/android_handler.html 前言 Android的消息传递机制是另外一种形式的“事件处理”,这种机制主要是为了 ...
- PowerDesigner将PDM导出生成WORD文档--温习老知识
转:http://www.cnblogs.com/wudiwushen/archive/2010/05/13/1734812.html 今天的温习老知识,是如何将一个PD设计的PDM来导出WORD文档 ...
- Linux学习笔记22——线程属性(转)
本文来自博客园:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764204.html 一.线程属性线程具有属性,用pthread_at ...
- 【索引】UML学习笔记
行为图 交互图 交互概览图 时间图 顺序图 通信图 活动图 状态及图 用例图 结构图 包图 类图 对象图 组件图 部署图 组合结构图
- TOYS - POJ 2318(计算几何,叉积判断)
题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数. 分析:做的第一道计算几何题目....使用叉积判断方 ...
- NIO与普通IO文件读写性能对比
最近在熟悉java的nio功能.nio采用了缓冲区的方式进行文件的读写,这一点更接近于OS执行I/O的方式.写了个新旧I/O复制文件的代码,练练手,顺便验证一下两者读写性能的对比,nio是否真的比普通 ...
- winform设置DataGridView样式 (蓝色)
本文转载:http://www.cnblogs.com/hailexuexi/archive/2012/04/23/2466398.html 代码: #region DataGridVeiw Styl ...
- BloomFilter--大规模数据处理利器
Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合. 一. 实例 为了说明Bl ...
- Android无法更新sdk的解决办法
修改 windows/system32/drivers/etc/hosts 文件 添加 203.208.46.146 dl.google.com203.208.46.146 dl-ssl.google ...
- ★ Linked List Cycle II -- LeetCode
证明单链表有环路: 本文所用的算法 能够 形象的比喻就是在操场其中跑步.速度快的会把速度慢的扣圈 能够证明,p2追赶上p1的时候.p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上 我们能够 ...