hdu 2795 段树--点更新

http://acm.hdu.edu.cn/showproblem.php?pid=2795

在第一和第三多学校都出现线段树,我在比赛中并没有这样做。,热身下,然后31号之前把那两道多校的线段树都搞了,这是一道热身题

关键是建模:

首先一定看清楚题目构造的场景,看有什么特点--------会发现。假设尽量往左上放置的话。那么因为 the i-th announcement is a rectangle of size 1 * wi.,全然能够对h建立线段树。表示一行。结点里的l,r就表示从l行到r行,每次插入都更新结点里的可用宽度,同一时候插入的时候记录行数即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define lson(i) (i)*2,l,mid
#define rson(i) ((i)*2+1),mid+1,r
#define ll rt*2
#define rr (rt*2+1)

const int MAXN = 200000 +10;
int n,w,h;
struct Node
{
    int l,r;
    int up;
}nodes[MAXN*4];

void build(int rt, int l, int r)
{
    nodes[rt].l=l;
    nodes[rt].r=r;
    nodes[rt].up=w;
    if(l == r)return;
    int mid=(l+r)/2;
    build(lson(rt));
    build(rson(rt));
}
int cnt;
int ans[MAXN];
void update(int rt,int v)
{
    if(nodes[rt].l == nodes[rt].r)
    {
        nodes[rt].up-=v;
        ans[cnt]=nodes[rt].l ;
        return;
    }
    if(v<=nodes[rt*2].up)update(rt*2,v);
    else update(rt*2+1,v);
    nodes[rt].up=max(nodes[rt*2].up, nodes[rt*2+1].up);
}


int main()
{
    int y;
    while(~scanf("%d%d%d",&h, &w, &n))
    {
        cnt=0;
        h=min(h,n);
        build(1,1,h);
        memset(ans,-1,sizeof(ans));
        for(int i=0;i<n;i++)
        {
             scanf("%d",&y);
             if(nodes[1].up>=y)update(1,y);
             cnt++;
        }
        for(int i=0;i<n;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值