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\n",ans);

91         }

92     }

93     return 0;

94 }
View Code

 

你可能感兴趣的:(poj)