hdu2795Billboard 线段树

//给一个h*w的广告板
//在上面贴广告,每个广告的宽度为1,长度为wi
//广告要求尽可能高,在高的前提下往左放
//给n个广告的长度,问其高度位置
//用线段树存入区间的最大的剩余区间
//每次查询大于该广告的长度的最左值
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 200010 ;
#define left v<<1
#define right v<<1|1
struct node
{
    int l , r ;
    int value;
}tree[maxn<<2] ;
int h , w , n ;
void build(int l , int r , int v)
{
    tree[v].l = l ;
    tree[v].r = r;
    tree[v].value = w ;
    if(l==r)return ;
    int mid = (l + r) >> 1 ;
    build(l , mid , left) ;
    build(mid+1  , r , right) ;
}
int update(int v , const int num)
{
    if(tree[v].l == tree[v].r)
    {
        tree[v].value -= num ;
        return tree[v].l;
    }
    int mid = (tree[v].l + tree[v].r) >> 1 ;
    int ans ;
    if(tree[left].value >= num)
    ans =  update(left ,num) ;
    else if(tree[right].value >= num)
    ans = update(right,num) ;
    tree[v].value = max(tree[left].value , tree[right].value) ;
    return ans ;
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    while(~scanf("%d%d%d" , &h , &w , &n))
    {
        int a ;
        build(1 , min(h,n) , 1) ;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d" ,&a) ;
            if(tree[1].value < a)
            puts("-1") ;
            else
            printf("%d\n" , update(1 , a)) ;
        }
    }
    return  0 ;
}































































































你可能感兴趣的:(hdu2795Billboard 线段树)