hdu 2795 Billboard

来源:互联网 发布:做淘宝的流程 编辑:程序博客网 时间:2024/06/04 01:07

题目大意:
给一个h*w的公告牌,h是高度,w是宽度,一个单位高度1为一行,然后会有一些公告贴上去,公告是1*wi大小的长纸条,优先贴在最上面并且最左边的位置,如果没有空间贴得下,就输出-1,可以的话,就输出所贴的位置(第几行)。

分析:
叶节点【x,x】表示board的第x行还可以放置的长度,区间【a,b】表示第a行到b行中剩下空间最大的那一行是多少,如果要把长w的公告放入board时就是update,优先往左子树走(如果左子树的空间足够的话),一直走到叶节点,更新这个叶节点剩下的长度,然后再向上更新。

由于h最大为10^9, n最大才20W,所以h组多也只需要用到20W,只需要取min(h,n)即可。


单点更新

区间求最大值的位置,Update操作在Queue里面。

 

#include<cstdio>#include<algorithm>using namespace std;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const int maxn = 200010;int sum[maxn<<2];int h,w,n;void PushUP(int rt){    sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){    sum[rt] = w;    if(l==r) return;    int m = (l+r)>>1;    build(lson);    build(rson);}int Queue(int v,int l,int r,int rt){    if(l == r)    {        sum[rt]-=v;        return l;    }    int m = (l+r)>>1;    int res;    if(v <= sum[rt<<1]) res=Queue(v,lson);    else res=Queue(v,rson);    PushUP(rt);    return res;}int main(){    while(scanf("%d%d%d",&h,&w,&n)!=EOF)    {        if(h>n) h=n;        build(1,h,1);        for(int i=0;i<n;i++)        {            int x;            scanf("%d",&x);            if(sum[1]<x) puts("-1");            else printf("%d\n",Queue(x,1,h,1));        }    }    return 0;}


0 0
原创粉丝点击