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;
const int N = 2e5 + 10;
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch))  x = x * 10 + ch - 48, ch = getchar();
}
inline int print (int x) {
    if (x < 0) putchar ('-'), x = -x;
    if (x > 9) print (x / 10);
    putchar (x % 10 + 48);
}
int h, w, n, val, c[N << 2];
#define ls p << 1
#define rs p << 1 | 1
inline int Max (int a, int b) {return a > b ? a : b;}
int query (int p, int l, int r, int val) {
    if (l == r) {
        if (c[p] >= val) {c[p] -= val; return l;}
        else return -1;
    }
    int mid (l + r >> 1), ans (-1);
    if (c[ls] >= val) ans = query (ls, l, mid, val);
    else if (c[rs] >= val) ans = query (rs, mid + 1, r, val);
    c[p] = Max (c[ls], c[rs]);
    return ans;
}
int main() {
    while (~scanf ("%d %d %d", &h, &w, &n)) {
        if (n < h) h = n;
        for (int i = 1; i <= (h << 2); ++i) c[i] = w;
        for (int i = 1; i <= n; ++i) {
            read (val);
            if (val > w) puts ("-1");
            else print (query (1, 1, h, val)), puts ("");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/whx666/p/12041534.html

时间: 2024-10-14 00:48:38

HDU2795 Billboard 题解的相关文章

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 线段树 单点更新

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(线段树)

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

线段树专题—HDU2795 Billboard

题意:给一块h*w广告板,然后给n个1*wi的广告条,广告条放的顺序是有限选择向上的,再优先选择左边的,对于每块广告条,输出它放的位置,如果放不下,输出-1 分析:很简单的单点更新max值的线段树,思路很好想,以广告板的每个高度建树,更新点的时候优先选择高度值小的点. 注意:比较容易出错的是 ,要注意h的范围啊1e9!!!,直接以这个高度建树肯定爆啊,这里注意到n是200000,也就是说高度最多建这么多就够了,因为上面的板都放不下了,下面肯定也用不到的. 代码: #include <iostre

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树

(转载)线段树模板(来自胡浩大牛)

http://www.notonlysuccess.com/(今天看二叉树,想回来看看,发现大牛博客进不去...) 如果要学,就要好好学.我copy的,如有错,请看http://www.cnblogs.com/Mu-Tou/archive/2011/08/11/2134427.html [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时觉得挺自豪的,还去pku打广告,但是现在我自己都不太好意思去看那篇文章了,觉得当时的代码风格实在是太丑了,很多线段树的初学者