Hdu 2795 Billboard

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

题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子
思路:每次找到最大值的位子,然后减去L,线段树区间求最值。

本题可以先Query再Update,也可以Query和Update一起来。后者明显要快一些:

//分开写

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define Maxn 200005
#define lx (x<<1)
#define rx ((x<<1)| 1)
#define MID ((l + r)>>1)

int h,w,n;
int A[Maxn];
int S[Maxn<<2];
void pushUp(int x)
{
    S[x] = max(S[lx],S[rx]);
}
void build(int l,int r,int x)
{
    if(l == r)
    {
        S[x] = w;
        return;
    }
    build(l,MID,lx);
    build(MID+1,r,rx);
    pushUp(x);
}
void update(int p,int d,int l,int r,int x)
{
    if(l == r)
    {
        S[x] -= d;
        return;
    }
    if(p<=MID) update(p,d,l,MID,lx);
    else update(p,d,MID+1,r,rx);
    pushUp(x);
}
int query(int t,int l,int r,int x)
{
    int ans = 0;
    if(l == r)
    {
        return l;
    }
    if(t<=S[lx]) ans = query(t,l,MID,lx);
    else ans = query(t,MID+1,r,rx);
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t;
    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++)
        {
            scanf(" %d",&t);
            if(t>S[1]) puts("-1");
            else
            {
                int temp = query(t,1,h,1);
                printf("%d\n",temp);
                update(temp,t,1,h,1);
            }
        }
    }
    return 0;
}
//Query中Update
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define Maxn 200005
#define lx (x<<1)
#define rx ((x<<1)| 1)
#define MID ((l + r)>>1)

int h,w,n;
int A[Maxn];
int S[Maxn<<2];
void pushUp(int x)
{
    S[x] = max(S[lx],S[rx]);
}
void build(int l,int r,int x)
{
    if(l == r)
    {
        S[x] = w;
        return;
    }
    build(l,MID,lx);
    build(MID+1,r,rx);
    pushUp(x);
}

int query(int t,int l,int r,int x)
{
    int ans = 0;
    if(l == r)
    {
        S[x] -= t;
        return l;
    }
    if(t<=S[lx]) ans = query(t,l,MID,lx);
    else ans = query(t,MID+1,r,rx);
    pushUp(x);
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t;
    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++)
        {
            scanf(" %d",&t);
            if(t>S[1]) puts("-1");
            else printf("%d\n",query(t,1,h,1));
        }
    }
    return 0;
}



你可能感兴趣的:(Hdu 2795 Billboard)