首页 > 代码库 > HDU 2795 Billboard (线段树 单点更新 区间求最大值)
HDU 2795 Billboard (线段树 单点更新 区间求最大值)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2795
题意:有一块h*w 的广告版,有n块1*w[i]的广告,就着放广告尽量在顶上,尽量先放左边的原则,问在第几行能把广告放下,如果放不下,就打印-1;
思路:我们可以根据每一行建树,每一个子叶表示每一行的容量,而节点存放子节点的最大值,然后从最顶到底,快速查找能存放下广告的一行。
总之还是简单的线段树问题,难点在于抽象模型。
#include <iostream> #include <cstdio> #define MID (l + r) >> 1 #define LS rt << 1 #define RS rt << 1 | 1 #define LSON l,m,rt << 1 #define RSON m + 1,r,rt << 1 | 1 #define MAX 999999 using namespace std; int imax[MAX << 2]; inline void pushup(int rt) { imax[rt] = max(imax[LS],imax[RS]); } void build(int w,int l,int r,int rt) { if(l == r) { imax[rt] = w; return ; } int m = MID; build(w,LSON); build(w,RSON); pushup(rt); } int query(int x,int l,int r,int rt) { if(l == r) { imax[rt] -= x; return l; } int m = MID; int ret = (imax[LS] >= x) ? query(x,LSON) : query(x,RSON); pushup(rt); return ret; } int main() { int h,w,n; while(~scanf("%d%d%d",&h,&w,&n)) { //优化:如果空间远远更能够h>n,那么就让h=n(一行一条广告) if(h > n) h = n; build(w,1,h,1); while(n--) { int x; scanf("%d",&x); if(imax[1] < x) //如果最顶端没有位置 puts("-1"); else printf("%d\n",query(x,1,h,1)); } } return 0; }
HDU 2795 Billboard (线段树 单点更新 区间求最大值)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。