hdu 2795(线段树)
2015-10-29 13:37
260 查看
题目链接:点击打开链接
题目大意:有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠左; 求第n个广告的所在的位置,不能贴则为-1; (翻译摘自博客jarily, 有点懒了)
题目分析:最多有2*10^5这么多的广告牌,如果从上到下找第一个合适的肯定会超时的; 最差可能O(n^2); 这里就需要灵活运用线段树了。 线段树中的节点保存最大的剩余空间。。。怎么在最前面呢,如果左儿子的最大剩余空间存在,优先访问左儿子(从上到下的广告牌剩余空间在线段树中对应的位置依次从左到右), 到这里看代码很快就明白我要说的了;
参考代码:
题目大意:有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴上去; 而且要求广告要尽量往上贴并且尽量靠左; 求第n个广告的所在的位置,不能贴则为-1; (翻译摘自博客jarily, 有点懒了)
题目分析:最多有2*10^5这么多的广告牌,如果从上到下找第一个合适的肯定会超时的; 最差可能O(n^2); 这里就需要灵活运用线段树了。 线段树中的节点保存最大的剩余空间。。。怎么在最前面呢,如果左儿子的最大剩余空间存在,优先访问左儿子(从上到下的广告牌剩余空间在线段树中对应的位置依次从左到右), 到这里看代码很快就明白我要说的了;
参考代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 200000+10; int h, w, n, maxv[4*maxn]; int x; int query(int o, int L, int R){ if(L == R) { maxv[o] -= x; return L; } // 点修改在查询中顺便完成了; int M = L + (R-L)/2; int ret = (maxv[o*2] >= x) ? query(o*2, L, M) : query(o*2+1, M+1, R); maxv[o] = max(maxv[o*2], maxv[o*2+1]); // 有过修改必须在回溯中维护节点内容; return ret; } int main() { while(~scanf("%d%d%d", &h, &w, &n)){ if(h > n) h = n; for(int i = 1; i < 4*h; ++i) maxv[i] = w; for(int i = 0; i < n; ++i){ scanf("%d", &x); if(x > maxv[1]) printf("-1\n"); else printf("%d\n", query(1, 0, h-1)+1); } } return 0; }
相关文章推荐
- sqlserver 查询效率优化
- HighCharts常用属性查找
- 黄聪:C#超级延时方法,延迟系统时间但系统又能同时能执行其它任务
- Could not build module ‘libxmlSimu'
- 素数的分布
- java面试
- 字符串问题归类--C和C++
- 自定义checkbox,自定义button
- <学习笔记>ArcGIS Runtime for Android 10.2.5配置+baseMap
- Swing事件分发线程
- 2015年10月26日作业
- java 获取系统时间
- 解决CocoaPods在OS X 10.11上出现的问题
- Linux 技巧:让进程在后台可靠运行的几种方法
- oracle存储过程常用技巧
- Leetcode Container With Most Water
- Tomcat Disable Session
- 个人笔记 css 01 开启chrome浏览器GPU加速模式
- ListView 嵌套 GridView 大法
- 增加略过超链接的上面图片一起变色