Hdu 2795 Billboard 单点更新,区间最值

来源:互联网 发布:老电视如何看网络电视 编辑:程序博客网 时间:2024/06/07 04:03

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795

题目大意:给你w*h的张贴板,现在给你N个高为1长为xi的海报,海报只能横着贴且不允许重叠,问第i张海报能否贴上,如过能则输出最上面能贴在第几行。

解题思路:将张贴板的每行长度看做一个大小为w的数字,每次贴进去一张海报,长度减去xi,节点中保存能张贴的最长的海报长度。

代码如下:

#include<stdio.h>#include<algorithm>#include<cstring>using namespace std;#define N 200005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int Max[N<<2],h,w,n;void pushup(int rt){    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);}void build(int l,int r,int rt){    Max[rt]=w;    if(l==r) return;    int m=(l+r)>>1;    build(lson);    build(rson);    pushup(rt);}int query(int x,int l,int r,int rt){    if(l==r)    {       Max[rt]-=x;       return l;    }    int m=(l+r)>>1;    int ret;    ret=Max[rt<<1]>=x?query(x,lson):query(x,rson);    pushup(rt);    return ret;}int main(){    while(~scanf("%d%d%d",&h,&w,&n))    {        int x;        if(h>n) h=n;        build(1,h,1);        for(int i=1;i<=n;i++)        {            scanf("%d",&x);            if(x>Max[1])                printf("-1\n");            else                printf("%d\n",query(x,1,h,1));        }    }    return 0;}


 

0 0
原创粉丝点击