poj 2104 划分树模板

划分树的模板题。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 100001;
 7 int tree[20][N];
 8 int sum[20][N];
 9 int as[N];
10 
11 void build( int p, int l, int r )
12 {
13     int mid = ( ( l + r ) >> 1 );
14     int lm = 0, ls = l, rs = mid + 1;
15     for ( int i = mid; i >= l; i-- )
16     {
17         if ( as[i] == as[mid] )
18             lm++;
19         else
20             break;
21     }
22     for ( int i = l; i <= r; i++ )
23     {
24         if ( i == l )
25             sum[p][i] = 0;
26         else
27             sum[p][i] = sum[p][i - 1];
28         if ( tree[p][i] == as[mid] )
29         {
30             if ( lm )
31             {
32                 lm--;
33                 sum[p][i]++;
34                 tree[p + 1][ls++] = tree[p][i];
35             }
36             else
37             {
38                 tree[p + 1][rs++] = tree[p][i];
39             }
40         }
41         else if ( tree[p][i] < as[mid] )
42         {
43             sum[p][i]++;
44             tree[p + 1][ls++] = tree[p][i];
45         }
46         else
47         {
48             tree[p + 1][rs++] = tree[p][i];
49         }
50     }
51     if ( l == r )
52         return ;
53     build( p + 1, l, mid );
54     build( p + 1, mid + 1, r );
55 }
56 
57 int query( int p, int l, int r, int ql, int qr, int k )
58 {
59     if ( l == r )
60         return tree[p][l];
61     int mid = ( ( l + r ) >> 1 );
62     int s, ss;
63     if ( ql == l )
64         s = 0, ss = sum[p][qr];
65     else
66         s = sum[p][ql - 1], ss = sum[p][qr] - s;
67     if ( k <= ss )
68         return query( p + 1, l, mid, l + s, l + sum[p][qr] - 1, k );
69     else
70         return query( p + 1, mid + 1, r, mid + 1 - l + ql - s, mid + 1 - l + qr - sum[p][qr], k - ss );
71 }
72 
73 int main ()
74 {
75     int n, m;
76     while ( scanf("%d%d", &n, &m) != EOF )
77     {
78         for ( int i = 1; i <= n; i++ )
79         {
80             scanf("%d", as + i);
81             tree[0][i] = as[i];
82         }
83         sort( as + 1, as + 1 + n );
84         build( 0, 1, n );
85         while ( m-- )
86         {
87             int a, b, c;
88             scanf("%d%d%d", &a, &b, &c);
89             printf("%d\n", query( 0, 1, n, a, b, c ));
90         }
91     }
92     return 0;
93 }

 

转载于:https://www.cnblogs.com/huoxiayu/p/4651569.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值