POJ2104 K-th Number 划分树求区间第K大数
2011-07-24 18:56
204 查看
Problem Address:http://poj.org/problem?id=2104
【前言】
如果是多次查询数组任意区间的最值,那么线段树或者树状数组都可以,后者更易实现。
但是如果是多次查询数组任意区间的第K最值,那么用划分树就更好。
虽然看着还是不太明白,但还是写写报告吧,方便以后做模板。
暂无思路,等以后想清楚了再来写。
这里是递归建树和递归查询。
划分树占用空间比较大。
【代码】
【前言】
如果是多次查询数组任意区间的最值,那么线段树或者树状数组都可以,后者更易实现。
但是如果是多次查询数组任意区间的第K最值,那么用划分树就更好。
虽然看着还是不太明白,但还是写写报告吧,方便以后做模板。
暂无思路,等以后想清楚了再来写。
这里是递归建树和递归查询。
划分树占用空间比较大。
【代码】
#include <iostream> #include <algorithm> using namespace std; const int maxn = 100000; int num[maxn+5]; int tree[21][maxn+5]; int leftsum[21][maxn+5]; void build_tree(int l, int r, int d) { int i; if (l==r) return; int mid = (l+r)>>1; int cl = l, cr = mid+1, stm = 0; for (i=mid; i>=l && num[mid]==num[i]; i--, stm++);//记录中点左边与中位数相等的数的个数 for (i=l; i<=r; i++) { if (i==l) leftsum[d][i] = 0; else leftsum[d][i] = leftsum[d][i-1]; if (tree[d][i]<num[mid]) { tree[d+1][cl] = tree[d][i]; cl++; leftsum[d][i]++; } else if (tree[d][i]==num[mid] && stm>0)//处理中点左边与中位数相等的数 { tree[d+1][cl] = tree[d][i]; cl++; leftsum[d][i]++; stm--; } else { tree[d+1][cr] = tree[d][i]; cr++; } } build_tree(l, mid, d+1); build_tree(mid+1, r, d+1); } int query(int d, int left, int right, int l, int r, int k) { if (l==r) return tree[d][r]; int ls, rs, mid; if (l==left) ls = 0; else ls = leftsum[d][l-1]; rs = leftsum[d][r]; mid = (left+right)>>1; if (rs-ls<k) return query(d+1, mid+1, right, l-left-ls+mid+1, r-left-rs+mid+1, k-rs+ls);//查询中的关键两行 else return query(d+1, left, mid, left+ls, left+rs-1, k); } int main() { int n, m; int i; int x, y, z; scanf("%d %d", &n, &m); for (i=1; i<=n; i++) { scanf("%d", &num[i]); tree[0][i] = num[i]; } sort(num+1, num+n+1); build_tree(1, n, 0); for (i=0; i<m; i++) { scanf("%d %d %d", &x, &y, &z); printf("%d\n", query(0, 1, n, x, y, z)); } return 0; }
相关文章推荐
- POJ 2104 K-th Number 主席树(求区间第k大)
- 划分树求区间第k值
- POJ 2104 K-th Number (主席树 静态区间第K大)
- POJ-2104 K-th Number (主席树 不带修改区间第k大)
- 小胖的疑惑 【整数划分 区间DP】
- POJ 2104 K-th Number (划分树,主席树写过了,这次是整体二分解法 )
- HDU 4251 The Famous ICPC Team Again 划分树 区间第K大
- POJ 2104 K-th Number(区间第k大数)(平方分割,归并树,划分树)
- zoj 3574 求给定区间内n条线段能将区间内的区域划分成几个区域
- nyoj746整数划分(四)【区间dp】
- poj 2104 K-th Number 区间第K大 二分 离散化 + (莫队 树状数组/平方分解/线段树)
- 区间dp模型(石子归并,括号匹配,整数划分)
- POJ 2104 K-th Number 区间第K大,可持久化线段树
- 划分dp,区间差最小
- 整数划分(区间dp)
- poj2761Feed the dogs(划分树-区间K值)
- 【转】pku 2104 K-th Number 求某区间第k小数 归并排序+线段树
- poj 2104 K-th Number 划分树
- POJ 2104 K-th Number 划分树
- SDUT3146:Integer division 2(整数划分区间dp)