POJ 2104 K-th Number 划分树
2016-04-01 19:53
706 查看
题意:
查询区间第\(k\)大分析:
之前是用主席树做的,现在学一下划分树。学习链接
划分树的空间复杂度为\(O(nlogn)\),这点比主席树更优。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100000 + 10; const int maxd = 20; int n, m; int sorted[maxn]; int T[maxd][maxn], num[maxd][maxn]; void build(int d, int L, int R) { int M = (L + R) / 2; int lsame = M - L + 1; for(int i = L; i <= R; i++) if(T[d][i] < sorted[M]) lsame--; int lpos = L, rpos = M+1; for(int i = L; i <= R; i++) { if(i == L) num[d][i] = 0; else num[d][i] = num[d][i - 1]; if(T[d][i] < sorted[M] || (T[d][i] == sorted[M] && lsame)) { T[d+1][lpos++] = T[d][i]; num[d][i]++; if(T[d][i] == sorted[M]) lsame--; } else { T[d+1][rpos++] = T[d][i]; } } if(L < M) build(d + 1, L, M); if(M+1 < R) build(d + 1, M+1, R); } int query(int d, int L, int R, int qL, int qR, int k) { if(L == R) return T[d][L]; int M = (L + R) / 2; int cntl; if(L == qL) cntl = 0; else cntl = num[d][qL - 1]; int cntr = num[d][qR]; int cnt = cntr - cntl; if(cnt >= k) return query(d + 1, L, M, L + cntl, L + cntr - 1, k); else { cntl = qL - L - cntl; cntr = qR - L + 1 - cntr; return query(d + 1, M+1, R, M+1+cntl, M+cntr, k - cnt); } } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", sorted + i); T[0][i] = sorted[i]; } sort(sorted + 1, sorted + 1 + n); build(0, 1, n); while(m--) { int l, r, k; scanf("%d%d%d", &l, &r, &k); printf("%d\n", query(0, 1, n, l, r, k)); } return 0; }
相关文章推荐
- 使用WITH AS提高性能简化嵌套SQL
- pycharm新版注册
- Python特殊语法:filter、map、reduce、lambda
- osgCallback的实现方法
- Delphi面向对象设计的经验原则(61条)
- 软件工程结对作业02
- 十分钟轻松让你认识Entity Framework 7
- Java 正则表达式的匹配
- 关于带透明度的灰度层的show、hide
- Android MTK Launcher3 替换桌面图标
- Trie——电话簿
- .bash_profile
- VE设计#7 逻辑层Myset
- 前端敲门砖-简历分享
- 2016蓝桥杯C++A组第六题 寒假作业
- 《Pro Android Graphics》读书笔记之第四节
- Codeforces Round #346 (Div. 2) D. Bicycle Race
- TCP 聊天室
- 全排列问题、八皇后问题、组合问题的递归解法
- 在原装Win8操作系统的计算机上U盘安装CentOS6.5系统