【线段树四】HDU 2795 Billboard





Billboard

Time
Limit: 20000/8000 MS (Java/Others)    Memory Limit:
32768/32768 K (Java/Others)
Total Submission(s):
9045    Accepted Submission(s):
4021

Problem
Description

At
the entrance to the university, there is a huge rectangular billboard of
size h*w (h is its height and w is its width). The board is the place
where all possible announcements are posted: nearest programming
competitions, changes in the dining room menu, and other important
information.

On
September 1, the billboard was empty. One by one, the announcements
started being put on the billboard.

Each
announcement is a stripe of paper of unit height. More specifically, the
i-th announcement is a rectangle of size 1 * wi.

When
someone puts a new announcement on the billboard, she would always choose
the topmost possible position for the announcement. Among all possible
topmost positions she would always choose the leftmost
one.

If
there is no valid location for a new announcement, it is not put on the
billboard (that‘s why some programming contests have no participants from
this university).

Given
the sizes of the billboard and the announcements, your task is to find the
numbers of rows in which the announcements are placed.

Input

There
are multiple cases (no more than 40 cases).

The
first line of the input file contains three integer numbers, h, w, and n
(1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the
billboard and the number of announcements.

Each
of the next n lines contains an integer number wi (1 <= wi <= 10^9)
- the width of i-th announcement.

Output

For each announcement
(in the order they are given in the input file) output one number - the
number of the row in which this announcement is placed. Rows are numbered
from 1 to h, starting with the top row. If an announcement can‘t be put on
the billboard, output "-1" for this announcement.

Sample
Input

3 5 5

2

4

3

3

3

Sample
Output

1

2

1

3

-1

Author

[email protected]

Source

HDOJ
2009 Summer Exercise(5)

来源: <http://acm.hdu.edu.cn/showproblem.php?pid=2795>

题意:

知识点:区间范围取最大值。

叶子节点代表广告牌的宽度

#include<stdio.h>
#include <algorithm>

using
namespace std;
#define MAXN 200000
int
t[MAXN*4];
int h,w,n;
void PushUp(int index){
    t[index]=max(t[index*2],t[index*2+1]);
}
void
build(int l,int r,int
index){
    if(l==r){
 
      t[index]=w;
   
    return ;
   
}
    int mid=(l+r)/2;
    build(l,mid,index*2);
    build(mid+1,r,index*2+1);
    PushUp(index);
}
int
Query(int width,int l,int
r,int index){
    if(l==r){
        t[index]-=width;
 
      return l;//返回所在层数
 
  }
    int mid=(l+r)/2;
    int hh=0;
 
  if(t[index*2]>=width)
   
    hh=Query(width,l,mid,index*2);
    else
        hh=Query(width,mid+1,r,index*2+1);
    PushUp(index);
   
return hh;

}
int main(){
    while(~scanf("%d%d%d",&h,&w,&n)){
        if(h>n)//这里如果广告牌的高度大于通告的个数的话
 
      h=n;
     
  build(1,h,1);//是以广告牌的高度为范围建树
 
      int wi;
 
      for(int
i=1;i<=n;i++){
   
    scanf("%d",&wi);
        if(t[1]<wi)
   
        printf("-1\n");
        else
 
          printf("%d\n",Query(wi,1,h,1));

        }
 
  }
    return 0;
}

来自为知笔记(Wiz)

【线段树四】HDU 2795 Billboard,码迷,mamicode.com

时间: 2024-12-25 14:32:05

【线段树四】HDU 2795 Billboard的相关文章

hdu 2795 Billboard(线段树)

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

HDU 2795 Billboard(宣传栏贴公告,线段树应用)

HDU 2795 Billboard(宣传栏贴公告,线段树应用) ACM 题目地址:HDU 2795 Billboard 题意: 要在h*w宣传栏上贴公告,每条公告的高度都是为1的,而且每条公告都要尽量贴最上面最靠左边的,给你一系列的公告的长度,问它们能不能贴上. 分析: 不是很好想,不过想到了就很好写了. 只要把宣传栏倒过来就好办了,这时候就是变成有h条位置可以填公告,填放公告时就可以尽量找最左边的合适的位置来放了. 可以用线段树实现,查找的复杂度是O(logn),需要注意的坑点是h的范围非常

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

题意:h,w,n:有一个h*w尺寸的木板,n张1*wi的海报,贴海报的位置尽量高,尽量往左,问每张海报贴的高度 看到1 <= h,w <= 10^9; 1 <= n <= 200,000,应该就是线段树了. 关键在怎么建树,这里我们对h进行分割,每个高度都有等长的w,我们从上往下贴,如果当前高度 (在同一高度上l==r)的长度可以满足wi则可以贴,否则继续往下寻找. #include <iostream> #include <stdio.h> #includ

HDU 2795 Billboard (RE的可以看一看)

Problem Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, chang

【线段树】hdu 1166 敌兵布阵

[线段树]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时

【线段树】 HDU 5025 A Corrupt Mayor&#39;s Performance Art

更新区间内颜色 输出区间内的颜色总数 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <math.h> using namespace std; #include <

【线段树】hdu 1754 I Hate It

[线段树]hdu 1754 I Hate It 题目链接:hdu 1754 I Hate It 题目大意 N个学生的初始成绩已知,操作m次,每次要么将第i个学生的成绩更新,要么查找区间[x,y]的最大成绩. 很显然这是一道线段树,点修改.区间查询,笔者第三道线段树,完全自己敲的,直接AC~(≧▽≦)/~啦啦啦. 如果单纯查找区间最大值,时间复杂度O(N),而线段树O(logN),当查询的次数非常多时,显然后者更高效! 说一下思路 线段树的点修改[点更新]:直接将叶节点更新为输入的数据,对照"敌兵

【线段树】HDU 3397 Sequence operation 区间合并

操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters into '1's in [a , b] 2 a b change all '0's into '1's and change all '1's into '0's in [a, b] Output operations: 3 a b output the number of '1's in [a,

【线段树】hdu 1556 Color the ball

[线段树]hdu 1556 Color the ball 题目链接:hdu 1556 Color the ball 题目大意 给你N个气球,不断刷新指定区间的颜色,刷新N次,最后输出每一个气球的刷新次数. 上一篇文章是线段树的点修改.区间查询: 这篇文章是线段树的区间修改.点查询: 说一下思路 线段树的区间修改:利用线段树的区间查询,查询到叶节点segTree[root].sum++,而如果对区间进行多次点修改的话,注定超时 线段树的点查询:以为用之前的区间查询就可以了,实际上还是有改变,因为原