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 }

 

posted @ 2013-08-05 14:15  Naix_x  阅读(301)  评论(0)    收藏  举报