Billboard

Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 23138 Accepted Submission(s): 9570

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


解题心得:

  1. 这个线段树的建树方式和模板的不同,他是将题意上的公告版顺时针旋转九十度,也就是从公告板高的一半开始建立节点,l和r都代表的是高度,只有当l等于r的时候才可以w的加减,而他的父节点代表的是他的两个子节点的最大的值,方便在搜索的时候找到可以进行加减的高度。但是要注意有一个优先级就是先从上到下,从左到右,在找的时候要先从左方开始找。
  2. 建树的图大概就是这样(不太规范,看看就好):


代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+100;
struct node
{
int l,r,w;
}tree[maxn*4];
int h,w,n,ans; //父节点仅仅代表两个子节点的最大值,用来在搜索的时候看是否可以传递到他的子节点中void updata(int root)
{
tree[root].w = max(tree[root<<1].w,tree[root<<1|1].w);
} //先建一个树
void build_tree(int l,int r,int root)
{
tree[root].l = l,tree[root].r = r;
if(l == r)
{
tree[root].w = w;
return ;
}
int mid = (l + r) >> 1;
build_tree(l,mid,root<<1);
build_tree(mid+1,r,root<<1|1);
tree[root].w = w;
} void query(int num,int root)
{
if(num > tree[1].w)//当前公告版最大的空处都不能放下的时候答案为-1
{
ans = -1;
return ;
}
if(tree[root].l == tree[root].r)//只能够在最后一层子节点上面进行计算
{
tree[root].w -= num;
ans = tree[root].l;
return ;
}
if(tree[root<<1].w >= num)//先从左方开始找
query(num,root<<1);
else if(tree[root<<1|1].w >= num)
query(num,root<<1|1);
updata(root);//向上维护
} int main()
{
while(scanf("%d%d%d",&h,&w,&n) != EOF)
{
h = min(h,200000);
build_tree(1,h,1);
while(n--)
{
int now;
scanf("%d",&now);
query(now,1);
printf("%d\n",ans);
}
}
}

线段树:HDU2795-Billboard(建树方式比较新奇)的更多相关文章

  1. 线段树-hdu2795 Billboard(贴海报)

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

  2. kb-07线段树--10--dfs序建树

    /* hdu3974 dfs序建树,然后区间修改查询: */ #include<iostream> #include<cstdio> #include<cstring&g ...

  3. 关于使用lazytag的线段树两种查询方式的比较研究

    说到线段树,想来大家并不陌生——最基本的思路就是将其规划成块,然后只要每次修改时维护一下即可. 但是尤其是涉及到区间修改时,lazytag的使用往往能够对于程序的质量起到决定性作用(Ex:一般JSOI ...

  4. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  5. HDU 1754线段树基本操作,建树,更新,查询

    代码线段树入门整理中有介绍. #include<cstdio> #include<algorithm> #include<cstring> #include< ...

  6. codevs 2216 线段树 两种更新方式的冲突

    题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小宇航员夏令营”,在这里小可可不仅学到了丰富的宇航知识,还参与解决 ...

  7. hdu 2795 Billboard(线段树单点更新)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. [bzoj2752]高速公路 题解(线段树)

    2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2102  Solved: 887[Submit] ...

  9. 【ACM】hud1166 敌兵布阵(线段树)

    经验: cout 特别慢 如果要求速度 全部用 printf !!! 在学习线段树 内容来自:http://www.cnblogs.com/shuaiwhu/archive/2012/04/22/24 ...

随机推荐

  1. MapReduce错误之Error: java.lang.RuntimeException: java.lang.NoSuchMethodException的解决方法

    今天跑MapReduce项目的时候遇到了这个问题,日志如下所示: // :: DEBUG ipc.ProtobufRpcEngine: Call: getDiagnostics took 19ms E ...

  2. 宝塔面板安装的mysql5.5用命令行kill -9后启动不了

    1.查看mysql版本方法一:status;方法二:select version(); 2.Mysql启动.停止.重启常用命令a.启动方式1.使用 service 启动:[root@localhost ...

  3. webpack.config.js====插件purifycss-webpack,提炼css文件

    1. 安装:打包编译时,可以删除一些html中没有使用的选择器,如果html页面中没有class=a class="b"的元素,.a{}.b{}样式不会加载 cnpm instal ...

  4. UIcollectionView 实现 轮番图

    UICollectionView 用作轮番图的实现,demo 地址:https://github.com/SummerHH/YJCYCleCollectionVIew #import <UIKi ...

  5. sql 2008 中不能创建数据库关系图

    执行以下命令: ALTER AUTHORIZATION ON DATABASE::[databasename] TO sa [databasename] 为数据库名: 此方法借鉴于<老高> ...

  6. 有关在python中使用Redis(二)

    这里简单介绍下在python中使用如何使用hashset,set和list: 从list开始: 一般我们使用lpush对一个list进行初始化添加,但是如果需要不断往这个list里面加值,就要用rpu ...

  7. JavaScript中登录名的正则表达式及解析(0基础)

    简言 在JavaScript中,经常会用到正则表达式来进行模式匹配.例如,登录名验证,密码强度验证,字符串查找或替换等操作.现在就开始吧,零基础写出你的第一个正则表达式! 在做用户注册时,都会用到登录 ...

  8. iOS 应用架构 (二)

    iOS 客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来回答 iOS 应用架构中的种种问题,本文是其中的第二篇,主要讲 View 层的组织和调用方案.上篇主要讲 View ...

  9. put_user

    1. put_user Name put_user --    Write a simple value into user space. Synopsis put_user ( x, ptr); A ...

  10. WinForm 窗体API移动 API阴影

    窗体移动 //窗体移动API [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllI ...