您的位置:首页 > 其它

划分树 K-th Number

2013-10-11 19:41 232 查看
K-th NumberTime Limit:20000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64uSubmit StatusDescriptionYou are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics inthe array segment.That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.InputThe first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000).The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given.The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).OutputFor each question output the answer to it --- the k-th number in sorted a[i...j] segment.Sample Input
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
Sample Output
5
6
3
#include <iostream>#include <algorithm>#include <string.h>#define MAXN 100010using namespace std;class Node{public:int l, r;};class SGtree{public:Node node[MAXN << 2];int num_left[20][MAXN];int sg_node[20][MAXN];int parray[MAXN];void init();void Maketree(int i, int d, int l, int r);int Query(int i, int d, int x, int y, int k);}tree;void SGtree::init(){memset(num_left, 0, sizeof(0));memset(sg_node, 0, sizeof(sg_node));memset(node, 0, sizeof(node));}void SGtree::Maketree(int o, int d, int l, int r){node[o].l = l;node[o].r = r;if (l == r){return ;}int mid = (l + r) >> 1;int issame = mid - l + 1;for (int i = l; i <= r; i++){if (sg_node[d][i] < parray[mid]){issame--;}}int pl = l, pr = mid + 1;for (int i = l; i <= r; i++){if (i == l){num_left[d][i] = 0;}else{num_left[d][i] = num_left[d][i - 1];}if (sg_node[d][i] < parray[mid]){num_left[d][i]++;sg_node[d + 1][pl++] = sg_node[d][i];}if (sg_node[d][i] > parray[mid]){sg_node[d + 1][pr++] = sg_node[d][i];}if (sg_node[d][i] == parray[mid]){if (issame > 0){issame--;num_left[d][i]++;sg_node[d + 1][pl++] = sg_node[d][i];}else{sg_node[d + 1][pr++] = sg_node[d][i];}}}Maketree(2 * o, d + 1, l, mid);Maketree(2 * o + 1, d + 1, mid + 1, r);}int SGtree::Query(int i, int d, int x, int y, int k){int l = node[i].l;int r = node[i].r;int mid = (l + r) >> 1;if (l == r){return sg_node[d][x];}int lnum, ltornum;if (x == node[i].l){lnum = 0;}else{lnum = num_left[d][x - 1];}ltornum = num_left[d][y] - lnum;if (ltornum >= k){return Query(i * 2, d + 1, l + lnum, l + lnum + ltornum - 1, k);}else{int a = x - l - lnum;int b = y - x - ltornum;return Query(i * 2 + 1, d + 1, mid + a + 1, mid + a + b + 1, k - ltornum);}}void input(){int t, n, m, x, y, k;while (scanf("%d %d", &n, &m) != EOF){tree.init();for (int i = 1; i <= n; i++){scanf("%d", &tree.parray[i]);tree.sg_node[1][i] = tree.parray[i];}sort(tree.parray + 1, tree.parray + n + 1);tree.Maketree(1, 1, 1, n);while (m--){scanf("%d %d %d", &x, &y, &k);printf("%d\n", tree.Query(1, 1, x, y, k));}}}int main(){input();return 0;}
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: