hdu 2795 Billboard

//每行剩余的长度是线段树的叶子结点值,每贴一张声明,就更新一次

#include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #include<algorithm> using namespace std; const int MAXN = 200020; int len[MAXN << 2]; int h,w,flag; void getmax(int rt) { len[rt] = max(len[rt << 1], len[(rt << 1) + 1]); } void build(int l, int r , int rt) { len[rt] = w; //len保存的是rt这一行剩余的长度 if(l == r) { return; } int mid = ( l + r) >> 1; build( l, mid, rt << 1); build(mid + 1, r, (rt << 1) +1 ); } void update(int p, int l, int r, int rt) { if(l == r) { flag = 1; len[rt] -= p; printf("%d\n",l); return; } int mid = ( l + r) >> 1; if(p <= len[rt << 1]) //p先用长度剩余最少的那行 update(p, l, mid, rt << 1); else if( p <= len[(rt << 1) + 1]) update(p, mid + 1, r, (rt << 1) + 1); else { return; } getmax(rt); } int main() { int n,b; while(~scanf("%d%d%d",&h,&w,&n)) { h = min(h,n+1); // 写成h = min(h,n) 就不对,没想明白 build(1,h,1); for(int i = 0; i < n; i++) { flag = 0; scanf("%d",&b); update(b,1,h,1); if(!flag) printf("-1\n"); } } return 0; }

 

posted @ 2015-07-18 18:20  杨永华  阅读(92)  评论(0编辑  收藏  举报