题目:
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 ",query(1,h,1,x)); 47 } 48 } 49 } 50 return 0; 51 }