HDU 4417 Super Mario(划分树+二分)

题目链接

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <algorithm>

  4 using namespace std;

  5 #define lson l,m,rt<<1

  6 #define rson m+1,r,rt<<1|1

  7 #define N 100100

  8 struct node

  9 {

 10     int l,r;

 11 }tree[4*N];

 12 int sorted[N];

 13 int lnum[20][N];

 14 int val[20][N];

 15 void build(int d,int l,int r,int rt)

 16 {

 17     int m,lsame,i,lpos,rpos,same;

 18     tree[rt].l = l;

 19     tree[rt].r = r;

 20     if(l == r) return ;

 21     m = (l+r)>>1;

 22     lsame = (m - l + 1);

 23     for(i = l;i <= r;i ++)

 24     {

 25         if(val[d][i] < sorted[m])

 26         lsame --;

 27     }

 28     lpos = l;

 29     rpos = m+1;

 30     same = 0;

 31     for(i = l;i <= r;i ++)

 32     {

 33         if(i == l)

 34         lnum[d][i] = 0;

 35         else

 36         lnum[d][i] = lnum[d][i-1];

 37         if(val[d][i] < sorted[m])

 38         {

 39             lnum[d][i] ++;

 40             val[d+1][lpos++] = val[d][i];

 41         }

 42         else if(val[d][i] > sorted[m])

 43         {

 44             val[d+1][rpos++] = val[d][i];

 45         }

 46         else

 47         {

 48             if(same < lsame)

 49             {

 50                 same ++;

 51                 lnum[d][i] ++;

 52                 val[d+1][lpos++] = val[d][i];

 53             }

 54             else

 55             {

 56                 val[d+1][rpos++] = val[d][i];

 57             }

 58         }

 59     }

 60     build(d+1,lson);

 61     build(d+1,rson);

 62 }

 63 int query(int d,int k,int l,int r,int rt)

 64 {

 65     int s,ss,nl,nr,m,rs,rss;

 66     if(l == r)

 67     {

 68         return val[d][l];

 69     }

 70     if(l == tree[rt].l)

 71     {

 72         s = lnum[d][r];

 73         ss = 0;

 74     }

 75     else

 76     {

 77         s = lnum[d][r] - lnum[d][l-1];

 78         ss = lnum[d][l-1];

 79     }

 80     if(s >= k)

 81     {

 82         nl = ss + tree[rt].l;

 83         nr = ss + tree[rt].l + s - 1;

 84         return query(d+1,k,nl,nr,rt<<1);

 85     }

 86     else

 87     {

 88         m = (tree[rt].l + tree[rt].r)>>1;

 89         rss = l - tree[rt].l - ss;

 90         rs = r - l + 1 - s;

 91         nl = m + rss + 1;

 92         nr = m + rs + rss;

 93         return query(d+1,k-s,nl,nr,rt<<1|1);

 94     }

 95 }

 96 int bin(int l,int r,int key)

 97 {

 98     int str,end,mid,temp;

 99     str = 1;end = r-l+1;

100     while(str < end)

101     {

102         mid = (str + end + 1)/2;

103         temp = query(0,mid,l,r,1);

104         if(temp > key)

105         end = mid - 1;

106         else

107         str = mid;

108     }

109     return end;

110 }

111 int main()

112 {

113     int i,n,m,x,y,k,t,cas = 1;

114     scanf("%d",&t);

115     while(t--)

116     {

117         scanf("%d%d",&n,&m);

118         for(i = 1;i <= n;i ++)

119         {

120             scanf("%d",&val[0][i]);

121             sorted[i] = val[0][i];

122         }

123         sort(sorted+1,sorted+n+1);

124         build(0,1,n,1);

125         printf("Case %d:\n",cas++);

126         for(i = 0;i < m;i ++)

127         {

128             scanf("%d%d%d",&x,&y,&k);

129             x ++;

130             y ++;

131             if(k > query(0,y-x+1,x,y,1))

132             printf("%d\n",y-x+1);

133             else if(k < query(0,1,x,y,1))

134             printf("0\n");

135             else

136             printf("%d\n",bin(x,y,k));

137         }

138     }

139     return 0;

140 }

 

你可能感兴趣的:(super)