pku2761区间第k大数-二分+树状数组
2011-08-06 21:22
441 查看
http://poj.org/problem?id=2761
题意:给定一个数组,求一些区间的第k大数,数据比2104大10倍,开始没怎么看题,直接贴代码tle了。。。这题有一个很重要的限制,那就是不存在包含关系的区间。。。
分析:那个限制条件是关键。。。在那个限制条件下,我们能很自然的想到对查询排序,从从前往后扫,逐渐加点,删点。。。。剩下的工作就和xmu那题一样了。。。。
注意用树状数组需要先离散化。。。
代码:
题意:给定一个数组,求一些区间的第k大数,数据比2104大10倍,开始没怎么看题,直接贴代码tle了。。。这题有一个很重要的限制,那就是不存在包含关系的区间。。。
分析:那个限制条件是关键。。。在那个限制条件下,我们能很自然的想到对查询排序,从从前往后扫,逐渐加点,删点。。。。剩下的工作就和xmu那题一样了。。。。
注意用树状数组需要先离散化。。。
代码:
#include<algorithm> #include<iostream> #include<map> using namespace std; const int N=100010; int sum , ans , c , n, m;//c存离散化后某个值对应的真值 struct lisan { int i, ii, v; //ii为原来数组的序号,i为离散化后的值 }b ; struct node { int l, r, k, i; } a ; int cmp2(const lisan &a, const lisan &b) { return a.ii<b.ii; } int cmp1(const lisan &a, const lisan &b) { return a.v<b.v; } int cmp(const node &a, const node &b) { return a.l < b.l; } void update(int i, int v) { for(; i<=n; i+=i&(-i)) sum[i] += v; } int query(int i) { int tmp=0; for(; i>0; i-=i&(-i)) tmp += sum[i]; return tmp; } int bs(int k) { int l=1,r=n, mid, tmp; while(l<=r) { mid = (l+r)>>1; tmp = query(mid); if(tmp>=k) r = mid-1; else l = mid+1; } return c[l]; } int main() { int i, j, ll, rr; while(scanf("%d%d", &n, &m)!=EOF) { for(i=1; i<=n; i++) { scanf("%d", &b[i].v); b[i].ii = i; } sort(b+1, b+n+1, cmp1); b[1].i = 1; c[1] = b[1].v; for(i=1, j=1; i<=n; i++) { if(b[i].v!=b[i-1].v) b[i].i = ++j; else b[i].i = j; c[j] = b[i].v; } sort(b+1, b+n+1, cmp2); for(i=1; i<=n; i++) sum[i] = 0; for(i=0; i<m; i++) { scanf("%d%d%d",&a[i].l, &a[i].r, &a[i].k); a[i].i = i; } sort(a, a+m, cmp); ll = rr = 1; for(i=0; i<m; i++) { while(rr<=a[i].r) { update(b[rr].i, 1); rr++; } while(ll<a[i].l) { update(b[ll].i, -1); ll++; } ans[a[i].i] = bs(a[i].k); } for(i=0; i<m; i++) printf("%d\n", ans[i]); } return 0; }
相关文章推荐
- 求第k大连续区间和/第k大子序列和 - 二分+树状数组+前缀和(或主席树+堆)
- 【51nod】 第K大区间2(二分+树状数组)
- [PKU 2104 2761] 区间第k大(小)值
- 51nod 第K大区间2(二分+树状数组)
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
- HDU 4417 (二分 + 区间第k大)
- POJ 2104 && POJ 2761 (静态区间第k大,主席树)
- 51nod1686 第K大区间 【二分】
- 整体二分,区间第K小(CRB and Queries,HDU 5412)
- 51nod 1686 第K大区间 (二分+滑动窗口+离散化)
- 51nod 1686 第K大区间【离散化+二分】
- hdu-5700 区间交(二分+树状数组)
- BZOJ 3110 [Zjoi2013]K大数查询 (整体二分 + 树状数组或线段树处理区间合值)
- 51nod 1686 第K大区间 二分好题
- 51 NOD 1685 第K大区间2 二分+BIT
- 【二分+Two Pointers】51Nod 1686 第K大区间
- 51NOD 1686 第K大区间 二分
- POJ-2761-树状数组+第k小数+离散化
- poj 2104 K-th Number 区间第K大 二分 离散化 + (莫队 树状数组/平方分解/线段树)
- POJ 2761 Feed the dogs 主席树(区间第k大)