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;
}

hdu 2795 线段树--点更新,布布扣,bubuko.com

时间: 2024-10-26 21:52:59

hdu 2795 线段树--点更新的相关文章

HDU 2795 线段树单点更新

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 23498    Accepted Submission(s): 9687 Problem Description At the entrance to the university, there is a huge rectangular billboard of s

HDU 2795 (线段树 单点更新) Billboard

h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子. 每次找能放纸条而且是最上面的位置,询问完以后可以同时更新,所以可以把update和query写在同一个函数里. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 200000 + 10; 7 8 int _max[maxn <&l

HDU 4302 线段树单点更新,维护区间最大最小值

http://acm.hdu.edu.cn/showproblem.php?pid=4302 Problem Description Holedox is a small animal which can be considered as one point. It lives in a straight pipe whose length is L. Holedox can only move along the pipe. Cakes may appear anywhere in the p

HDU 1394(线段树单点更新)

题意:就是给出一串数,当依次在将第一个数变为最后一个数的过程中,要你求它的最小逆序数. 思路:可以用树状数组和线段数做.这里我是用线段树做的.建的是一棵空树,然后每插入一个点之前,统计大于这个数的有多少个,直到所有的数都插入完成,就结果了逆序树的统计. 要得出答案主要是利用了一个结论,如果是0到n的排列,那么如果把第一个数放到最后,对于这个数列,逆序数是减少a[i],而增加n-1-a[i]的. #include<iostream> #include<cstring> #includ

hdu 2795 线段树(二维问题一维化)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10961    Accepted Submission(s): 4863 Problem Description At the entrance to the university, there is a huge rectangular billboard of s

hdu 3308 线段树单点更新 区间合并

http://acm.hdu.edu.cn/showproblem.php?pid=3308 学到两点: 1.以区间端点为开始/结束的最长......似乎在Dp也常用这种思想 2.分类的时候,明确标准逐层分类,思维格式: 条件一成立: { 条件二成立: { } else { } } else { 条件二成立: { } else { } } 上面的这种方式很清晰,如果直接想到那种情况iif(条件一 &条件二)就写,很容易出错而且把自己搞乱,或者情况不全,,,我就因为这WA了几次 3.WA了之后 ,

POJ 2777 &amp;&amp; ZOJ 1610 &amp;&amp;HDU 1698 --线段树--区间更新

直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 -- 区间更新的话 分为 增减 或者 修改 主要就是个 laze 标记 就是延迟更新 对于区间更新的写法 一般是有2种 其一 仔细划分到每个细小的区间    另一 粗略划分 反正 ==我的代码里会给出2种写法 看自己喜好 hdu 1 //线段树 成段更新 ---> 替换 根结点的查询 2 3 #i

HDU 4578 线段树区间更新(确定区间操作的优先级)

HDU 4578 线段树区间更新 操作有: 区间所有数add(c) 区间所有数mul(c) 区间所有数set(c) 查询有: 区间所有数的p次方和(p>= 1 && p <= 3) 关键是区间更新的三种操作的优先级的确定清楚set>mul>add 关键是:down和update中对区间的更新操作是一回事,可以写成函数方便编程 //#pragma warning (disable: 4786) //#pragma comment (linker, "/STA

HDU 2795 线段树(转变思维方能改变世界)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9895    Accepted Submission(s): 4413 Problem Description At the entrance to the university, there is a huge rectangular billboard of si