hdu 2795 线段树--点更新

来源:互联网 发布:手机淘宝下载安装 编辑:程序博客网 时间:2024/06/06 01:32

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
原创粉丝点击