poj2761Feed the dogs(划分树-区间K值)

链接

这树着实不好理解啊

讲解http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html

对于找K值 右区间的确定不是太理解。。先当模板贴着吧

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 using namespace std;
 7 #define N 100010
 8 int tree[20][N],sum[20][N];//每层的数  及每层截止到i会放进左子树的个数
 9 int cu[N],xu[N];//原数据 及排序后的数据
10 void build(int c,int l,int r)
11 {
12     int i,m = (l+r)>>1;
13     int o = m-l+1,rp = m+1,lp = l;
14     for(i = l ; i <= m ; i++)//左子树中与xu[m]相同的个数
15     if(xu[i]<xu[m])
16     o--;
17     for(i = l ; i <= r ; i++)
18     {
19         if(i==l)
20         sum[c][i] = 0;
21         else
22         sum[c][i] = sum[c][i-1];//维护一下 到I为止被分配到左子树中的个数 
23         if(tree[c][i]==xu[m])
24         {
25             if(o)
26             {
27                 sum[c][i]++;
28                 o--;
29                 tree[c+1][lp++] = xu[m];//分配到左子树中
30             }
31             else
32             tree[c+1][rp++] = tree[c][i];
33         }
34         else if(tree[c][i]<xu[m])
35         {
36             sum[c][i]++;
37             tree[c+1][lp++] = tree[c][i];
38         }
39         else
40         tree[c+1][rp++] = tree[c][i];//分配到右子树中
41     }
42     if(l==r) return ;
43     build(c+1,l,m);
44     build(c+1,m+1,r);
45 }
46 int query(int a,int b,int k,int c,int l,int r)
47 {
48     if(l==r)
49     {
50         return tree[c][l];
51     }
52     int m = (l+r)>>1;
53     int s,ss;
54     if(a==l)//这里特殊处理一下 sum没初始化 不然不处理应该也可以
55     {
56         s = 0;
57         ss = sum[c][b];
58     }
59     else
60     {
61         s = sum[c][a-1];
62         ss = sum[c][b]-s;
63     }
64     if(k<=ss)
65     {
66         return query(l+s,l+s+ss-1,k,c+1,l,m);
67     }
68     else
69     return query(m-l+1+a-s,m-l+1+b-s-ss,k-ss,c+1,m+1,r);
70 
71 }
72 int main()
73 {
74     int i,n,m;
75     while(scanf("%d%d",&n,&m)!=EOF)
76     {
77         for(i = 1 ; i <= n ; i++)
78         {
79             scanf("%d",&cu[i]);
80             tree[0][i] = cu[i];
81             xu[i] = cu[i];
82         }
83         sort(xu+1,xu+n+1);
84         build(0,1,n);
85         while(m--)
86         {
87             int a,b,c;
88             scanf("%d%d%d",&a,&b,&c);
89             int ans = query(a,b,c,0,1,n);
90             printf("%d
",ans);
91         }
92     }
93     return 0;
94 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3319979.html