HDU 2795 Billboard

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2795

题意:h*w的空间,给出1*L的木板,要求放在最高层且能放进的位置,最高层为1,最底层为h。

思路:线段树算法。每个节点存储的值sum[rt]为当前区间的最大宽度。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define inf 0x7fffffff
 7 using namespace std;
 8 
 9 const int maxn=200000+10;
10 int sum[maxn*4];
11 int h,w,n,x;
12 void PushUP(int rt)
13 {
14     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
15 }
16 void build(int l,int r,int rt,int x)
17 {
18     sum[rt]=x;
19     if (l==r) return ;
20     int m=(l+r)>>1;
21     build(l,m,rt<<1,x);
22     build(m+1,r,rt<<1|1,x);
23 }
24 int query(int l,int r,int rt,int x)
25 {
26     if (l==r) {sum[rt] -= x ; return l; }
27     int m=(l+r)>>1;
28     int ret= (sum[rt<<1]>=x) ? query(l,m,rt<<1,x) : query(m+1,r,rt<<1|1,x);
29     PushUP(rt);
30     return ret;
31 }
32 int main()
33 {
34     while (cin>>h>>w>>n)
35     {
36         if (h>n) h=n;
37         build(1,h,1,w);
38         while (n--)
39         {
40             scanf("%d",&x);
41             if (sum[1]<x) printf("-1\n");
42             else printf("%d\n",query(1,h,1,x));
43         }
44     }
45     return 0;
46 }

 

posted @ 2014-02-23 14:22  huangxf  阅读(145)  评论(0编辑  收藏  举报