poj2104 K大数 划分树

题意:给定一个数列,求一个区间的第K大数

模板题, 其中的newl, newr 有点不明白.

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 const int M = 100005;
 5 int toLeft[20][M], tree[20][M], sorted[M];
 6 
 7 void build(int level, int left, int right)
 8 {
 9     if (left == right) return;
10     int i, mid = (left + right) >>1;
11     int suppose = mid - left + 1;
12     for (i=left; i<=right; i++)
13         if (tree[level][i] < sorted[mid])
14             suppose--;
15     int lpos = left, rpos = mid+1;
16     for (i=left; i<=right; i++)
17     {
18         if (i == left)
19             toLeft[level][i] = 0;
20         else
21             toLeft[level][i] = toLeft[level][i-1];
22         if (tree[level][i] < sorted[mid])
23         {
24             toLeft[level][i]++;
25             tree[level+1][lpos++] = tree[level][i];
26         }
27         else if (tree[level][i] > sorted[mid])
28         {
29             tree[level+1][rpos++] = tree[level][i];
30         }
31         else 
32         {
33             if (suppose != 0)
34             {
35                 suppose--;
36                 toLeft[level][i]++;
37                 tree[level+1][lpos++] = tree[level][i];
38             }
39             else
40                 tree[level+1][rpos++] = tree[level][i];
41         }
42     }
43     build(level+1, left, mid);
44     build(level+1, mid+1, right);
45 }
46 
47 int query(int level, int left, int right, int qleft, int qright, int k)
48 {
49     if (qleft == qright)
50         return tree[level][qright];
51     int s, ss, mid = (left + right)>>1;
52     if (left == qleft)
53     {
54         s = 0;
55         ss = toLeft[level][qright];
56     }
57     else
58     {
59         s = toLeft[level][qleft-1];
60         ss = toLeft[level][qright] - s;
61     }
62     int newl, newr;
63     if (k <= ss)
64     {
65         newl = left + s;
66         newr = left + s + ss -1;
67         return query(level+1, left, mid, newl, newr, k);
68     }
69     else
70     {
71         newl = mid-left+1+qleft-s;
72         newr = mid-left+1+qright-s-ss;
73         return query(level+1, mid+1, right, newl, newr, k-ss);
74     }
75 }
76 
77 int main()
78 {
79     int n, m;
80     int i;
81     while (scanf("%d%d", &n, &m) == 2)
82     {
83         for (i=1; i<=n; i++)
84         {
85             scanf("%d", &tree[0][i]);
86             sorted[i] = tree[0][i];
87         }
88         sort(sorted+1, sorted+n+1);
89         build(0,1,n);
90         int ql, qr, k;
91         for (i=0; i<m; i++)
92         {
93             scanf("%d%d%d", &ql, &qr, &k);
94             printf("%d\n", query(0, 1, n, ql, qr, k));
95         }
96     }
97     return 0;
98 }
View Code

 

posted @ 2013-06-28 18:36  旅行的蜗牛  阅读(139)  评论(0编辑  收藏  举报