hdu 2795 Billboard(单点更新,区间查询)
题意:
h*w的白板。
有n个广告牌,每个广告牌是1*wi。必须放置在白板的upmost中的leftmost。
输出n个广告牌放置在第几行。如果放不下,输出-1。
数据规格:
h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000)
思路:
每行最少放一个,所以最多需要n行。
这道题要早最靠左的放得下广告牌的行号。线段树,,
代码:
const int maxn = 200005; int maxs[maxn<<2]; int h,w,n; void PushUp(int rt){ maxs[rt] = max( maxs[rt<<1], maxs[rt<<1|1] ); } void build(int l,int r,int rt){ maxs[rt] = w; if(l == r) return; int m = (l + r) >> 1; build(lson); build(rson); } int query(int x,int l,int r,int rt){ if(l == r){ maxs[rt] -= x; return l; } int m = (l + r) >> 1; int ret; if( maxs[rt<<1] >=x ) ret = query(x,lson); else ret = query(x,rson); PushUp(rt); return ret; } int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF){ h = min(h,n); build(1,h,1); for(int i=1;i<=n;++i){ int x; scanf("%d",&x); if(x > maxs[1]) printf("-1\n"); else printf("%d\n",query(x,1,h,1)); } } }