poj 2104 and hdu 2665 划分树模板入门题
来源:互联网 发布:linux 查看磁盘信息 编辑:程序博客网 时间:2024/05/21 22:39
题意:
给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。
解析:
划分树入门。
bing神的模板。
坑爹的地方是把-l 看成了-1........
一直re。
代码:
poj 2104:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e5 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int tree[30][maxn]; //表示每层每个位置的值int sorted[maxn]; //排完序的数int toleft[30][maxn]; //toleft[p][i]表示第p层从1到i有多少个数在左边void build(int l, int r, int dep){ if (l == r) return; int mi = (l + r) >> 1; int same = mi - l + 1; //等于中位数的数字个数 for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi]) { same--; } } int lpos = l; int rpos = mi + 1; for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi])//比中位数小 { tree[dep + 1][lpos++] = tree[dep][i]; } else if (tree[dep][i] == sorted[mi] && same > 0) { tree[dep + 1][lpos++] = tree[dep][i]; same--; } else //比中位数大 { tree[dep + 1][rpos++] = tree[dep][i]; } toleft[dep][i] = toleft[dep][l - 1] + lpos - l; // - l 不是减一 } build(l, mi, dep + 1); build(mi + 1, r, dep + 1);}//查询区间第k大数int query(int L, int R, int l, int r, int dep, int k){ if (l == r) return tree[dep][l]; int mi = (L + R) >> 1; int cnt = toleft[dep][r] - toleft[dep][l - 1]; if (k <= cnt) { int nextl = L + toleft[dep][l - 1] - toleft[dep][L - 1]; int nextr = nextl + cnt - 1; return query(L, mi, nextl, nextr, dep + 1, k); } else { int nextr = r + toleft[dep][R] - toleft[dep][r]; int nextl = nextr - (r - l - cnt); return query(mi + 1, R, nextl, nextr, dep + 1, k - cnt); }}int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL int n, m; while (~scanf("%d%d", &n, &m)) { memset(tree, 0, sizeof(tree)); memset(toleft, 0, sizeof(toleft)); for (int i = 1; i <= n; i++)//start from 1 { scanf("%d", &tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted + 1, sorted + n + 1); build(1, n, 0); while (m--) { int fr, to, k; scanf("%d%d%d", &fr, &to, &k); printf("%d\n", query(1, n, fr, to, 0, k)); } } return 0;}
hdu 2665:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e5 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int tree[30][maxn]; //表示每层每个位置的值int sorted[maxn]; //排完序的数int toleft[30][maxn]; //toleft[p][i]表示第p层从1到i有多少个数在左边void build(int l, int r, int dep){ if (l == r) return; int mi = (l + r) >> 1; int same = mi - l + 1; //等于中位数的数字个数 for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi]) { same--; } } int lpos = l; int rpos = mi + 1; for (int i = l; i <= r; i++) { if (tree[dep][i] < sorted[mi])//比中位数小 { tree[dep + 1][lpos++] = tree[dep][i]; } else if (tree[dep][i] == sorted[mi] && same > 0) { tree[dep + 1][lpos++] = tree[dep][i]; same--; } else //比中位数大 { tree[dep + 1][rpos++] = tree[dep][i]; } toleft[dep][i] = toleft[dep][l - 1] + lpos - l; // - l 不是减一 } build(l, mi, dep + 1); build(mi + 1, r, dep + 1);}//查询区间第k大数int query(int L, int R, int l, int r, int dep, int k){ if (l == r) return tree[dep][l]; int mi = (L + R) >> 1; int cnt = toleft[dep][r] - toleft[dep][l - 1]; if (k <= cnt) { int nextl = L + toleft[dep][l - 1] - toleft[dep][L - 1]; int nextr = nextl + cnt - 1; return query(L, mi, nextl, nextr, dep + 1, k); } else { int nextr = r + toleft[dep][R] - toleft[dep][r]; int nextl = nextr - (r - l - cnt); return query(mi + 1, R, nextl, nextr, dep + 1, k - cnt); }}int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL int ncase; scanf("%d", &ncase); while (ncase--) { int n, m; scanf("%d%d", &n, &m); memset(tree, 0, sizeof(tree)); memset(toleft, 0, sizeof(toleft)); for (int i = 1; i <= n; i++)//start from 1 { scanf("%d", &tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted + 1, sorted + n + 1); build(1, n, 0); while (m--) { int fr, to, k; scanf("%d%d%d", &fr, &to, &k); printf("%d\n", query(1, n, fr, to, 0, k)); } } return 0;}
0 0
- poj 2104 and hdu 2665 划分树模板入门题
- POJ 2104 划分树模板题
- hdu 2665 划分树模板
- hdu 2665 (poj 2104) 划分树
- HDU 2665 Kth number(划分树入门题,纯套模板)
- poj 2104 K-th Number (划分树模板题)
- poj 2104 (划分树模板)
- hdu 2665 Kth number(划分树模板题)
- hdu 2665 Kth number(划分树模板)
- POJ 2104 & HDU 2665 K-th Number (划分树)
- POJ 2104 | HDU 2665 - K-th Number (划分树)
- 【划分树】 POJ 2104 HDU 2665 K-th Number 裸题
- 初学划分树,小见解之!POJ-2104/HDU-2665
- hdu 4251 划分树入门题
- poj 2104 K-th number (模板级划分树)
- poj 2104 K-th number (模板级划分树)
- POJ--2104--K-th Number【划分树模板】
- 划分树学习小记 Poj 2104+Poj 2761+Hdu 2665 (区间第k大数)
- Android里面涉及的几种多媒体以及相关属性(一)
- 像素深度(bpp)
- mysql数据类型详解
- Arithmetic overflow error converting expression to data type int.”
- Jetty实战之 安装 运行 部署
- poj 2104 and hdu 2665 划分树模板入门题
- C# NET DataTable转Excel 并 下载
- 数据结构与算法-如何计算时间复杂度
- 2.07-赋值运算符
- 中缀转后缀
- java多线程-专题-聊聊并发(一)深入分析Volatile的实现原理
- 360APK包与类更改分析
- console
- 命令执行分隔符辨析