hdu2795

题意:有一个h*w的木板,放置一些1*L的物品,将物品尽可能的往上面和左边放置。

思路:维护一个区间的可以容纳板子长度的最大值

AC代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <cstdlib>
 7
 8 using namespace std;
 9
10 const int maxn = 200000 + 10;
11
12 int h, w, n, x;
13
14 struct node
15 {
16     int l, r, v;
17
18 } b[maxn<<2];
19
20 void build(int l, int r, int i)
21 {
22     b[i].l = l;
23     b[i].r = r;
24     int m = (l + r) >> 1;
25     if(l == r) {
26         b[i].v = w;
27         return ;
28     }
29     build(l, m, i<<1);
30     build(m+1, r, i<<1|1);
31     b[i].v = max(b[i<<1].v, b[i<<1|1].v);
32 }
33
34 int Query(int id, int num, int i)
35 {
36     int ret;
37     if(b[i].l == b[i].r) {
38         b[i].v -= num;
39         return b[i].l;
40     }
41     else {
42         if(num <= b[i<<1].v) ret = Query(id, num, i<<1);
43         else ret = Query(id, num, i<<1|1);
44     }
45     b[i].v = max(b[i<<1].v, b[i<<1|1].v);
46     return ret;
47 }
48
49 int main()
50 {
51     //freopen("test.in", "r", stdin);
52     while(scanf("%d%d%d", &h, &w, &n) != EOF) {
53         int H = min(h, n);
54         build(1, H, 1);
55         for(int i = 1; i <= n; i++) {
56             scanf("%d", &x);
57             if(b[1].v < x) puts("-1");
58             else printf("%d\n", Query(1, x, 1));
59         }
60     }
61     return 0;
62 }

时间: 2024-10-29 14:21:03

hdu2795的相关文章

HDU-------(2795)Billboard(线段树区间更新)

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

HDU2795 Billboard 【线段树】+【单点更新】

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

【HDU2795】Billboard(线段树)

大意:给一个h*w的格子,然后给出多个1*w的板子往格子里面填,如果有空间尽量往上一行填满,输出行数,无法填补,则输出-1: 可以使用线段树转化问题,将每一排的格子数目放到每一个叶子节点上,然后每有一块板子,进行query查询靠左子树的第一个大于板子的叶子,进行update操作更新叶子.每个节点附权值max叶子节点即可.令一个小坑是h和w的范围是1e9,数组太大.试想如果格子高度h > 板子的个数n,那么我们只需要压缩格子到n个高度即可.所有给叶子节点的存储空间就能压缩成n的范围即1e6. 1

HDU2795 Billboard 题解

HDU2795 Billboard 线段树例题解析合集 题意:有一个h行w列的矩形,在里面横放m条大小为1*l[i]的小长方形,不能重叠,如果能放得下,输出能放下的最小行数,放不下输出-1 由于只有m个长方形,最多只需要m行(h范围很大),把h对m取min 然后维护每行剩下的值的区间最大值,查询时若左子树代表区间内的最大值>需要的长度,向左子树递归,否则考虑右子树,若长度都不够,答案为-1 #include <bits/stdc++.h> using namespace std; con

【HDU2795】Billboard

本质上,区间最大值: 高为区间长度,宽度为每个元素初始大小 PS:1 <= h,w <= 10^9,而n次放置都是放在可能位置的最上面 所以对于每一种case,取h和n的最小值建树 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=200010; 5 int n,h,w,len[N<<2]; 6 int max(int,int),query(int,int,

HDU2795 Billboard 线段树 单点更新

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

hdu2795 线段树

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

hdu2795 Billboard(线段树)

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

hdu2795 Billboard 线段树

题意: 给出一块h*w的广告牌,还有n张1*u的海报,海报尽量往上,左边的位置张贴,问每一张海报能贴的多高. 线段树单点修改. 注意:因为1 <= h,w <= 10^9; 1 <= n <= 200,000,但实际上,若h>n的话,最坏的情况下也只要用到前n行. 所以若h>n  则h=n 如果不加这一句,因为线段树的数组要开到h<<2这么大,又h<= 10^9,所以输入的h过大时会使开的数组过大.加了的话,就不会啦,n<<2是OK的. 1