HDU 2795

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=2795

线段树问题,线段树的每个叶子节点保存的是当前行还剩余的长度,每次查询找到满足条件的一行减去该条幅的长度。

有一个点要注意的是关于线段树建立的大小,虽然题目中行数最大是10^9,但是n最大是200000,也就是说,每个条幅占一行也不过200000。所以当h大于n时,让h = n,然后建树就好了。

 1 #include<stdio.h>
 2 #include<algorithm> 
 3 #define lson l,m,rt*2
 4 #define rson m+1,r,rt*2+1
 5 #define maxn 222222 //这里只需要比n大就能满足条件 
 6 using namespace std;
 7 int tree[maxn*4];
 8 int h,w,n;
 9 void pushup(int rt){
10     tree[rt] = max(tree[rt*2],tree[rt*2+1]);
11 }
12 void build(int l,int r,int rt){
13     tree[rt] = w;
14     if(l == r)
15         return;
16     int m = (l+r)/2;
17     build(lson);
18     build(rson);
19     pushup(rt);
20 }
21 int query(int l,int r,int rt,int x){
22     if(l == r){
23         tree[rt] -= x;
24         return l;
25     }
26     int m = (l+r)/2;
27     int temp;
28     if(tree[rt*2] >= x)
29         temp = query(lson,x);
30     else
31         temp = query(rson,x);
32     pushup(rt);
33     return temp;
34 }
35 int main(){
36     while(scanf("%d%d%d",&h,&w,&n)!=EOF){
37         if(h > n)
38             h = n;
39         build(1,h,1);
40         for(int i = 0;i<n;i++){
41             int x;
42             scanf("%d",&x);
43             if(tree[1] < x){
44                 puts("-1");
45             }else{
46                 printf("%d\n",query(1,h,1,x));
47             }
48         }        
49     }
50     return 0;
51 }

 

posted @ 2016-03-21 19:39  张秦遥  阅读(212)  评论(0编辑  收藏  举报