hdu 2795 Billboard 线段树

题目链接:Billboard

 

题意:

给你一个高度为h,宽为w的广告牌。你有n个广告,你需要把它们贴到广告牌上面

每一个广告的高度为1,宽度为vi

你要尽可能把广告往上面贴(也就是高度往1这个数字靠近),而且广告要尽可能的向左边靠近

 

如果一个广告可以贴到广告牌上面就输出高度,否则输出-1

 

题解:

题目上面说了广告要尽可能向上和左,那么我们可以维护一下广告牌每一行还有多少空闲的宽度

然后你发现h的大小是1e9,但是实际上不需要这么大,因为n的大小是200000,最多也就是每一个广告占一行,所以h最大就是200000

 

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=2e5+10;
const int INF=0x3f3f3f3f;
#define lson root<<1
#define rson (root<<1)|1
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
#define mem_(a) memset(a,-1,sizeof(a))
#define mem__(a) memset(a,INF,sizeof(a))
int tree[maxn<<2],arr[maxn];
int n,h,w,ans;
void push_up(int root)
{
    tree[root]=max(tree[root<<1],tree[root<<1|1]);
}
//void push_down(int root,int L,int R)
//{
//    if(lazy[root]!=0)
//    {
//        int mid=(L+R)>>1;
//        tree[root<<1]+=lazy[root]*(mid-L+1);
//        tree[root<<1|1]+=lazy[root]*(R-mid);
//        lazy[lson]+=lazy[root];
//        lazy[rson]+=lazy[root];
//        lazy[root]=0;
//    }
//}
void build(int root,int L,int R)
{
    if(L==R)
    {
        tree[root]=w;
        return;
    }
    int mid=(L+R)>>1;
    build(root<<1,L,mid);
    build(root<<1|1,mid+1,R);
    push_up(root);
}
void update(int root,int L,int R,int val)
{
    if(L==R)
    {
        ans=L;
        tree[root]-=val;
        return;
    }
    int mid=(L+R)>>1;
    if(tree[lson]>=val)
        update(root<<1,L,mid,val);
    else update(root<<1|1,mid+1,R,val);
    push_up(root);
}
//void update_interval(int root,int L,int R,int LL,int RR,int val)
//{
//    if(LL<=L && R<=RR)
//    {
//        tree[root]+=val*(R-L+1);
//        lazy[root]+=val;
//        return;
//    }
//    int mid=(L+R)>>1;
//    if(LL<=mid) update(lson,L,mid,LL,RR,val);
//    if(RR>mid) update(rson,mid+1,R,LL,RR,val);
//    push_up(root);
//}
//int query(int root,int L,int R,int val)
//{
//    if(L==R)
//    {
//        return L;
//    }
//    //push_down(root);
//    int mid=(L+R)>>1;
//    if(tree[root<<1]>=val) return query(root<<1,L,mid,val);
//    else if(tree[root<<1|1]>=val) return query(root<<1|1,mid+1,R,val);
//    else return -1;
//
//}
int main()
{
    while(~scanf("%d%d%d",&h,&w,&n))
    {
        int t=n;
        h=min(h,n);
        build(1,1,h);
        while(t--)
        {
            int x;
            scanf("%d",&x);
            if(tree[1]<x)
            {
                printf("-1\n");
                continue;
            }
            update(1,1,h,x);
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

posted @ 2020-09-21 22:06  kongbursi  阅读(101)  评论(0编辑  收藏  举报