hdu-2795 Billboard(线段树)
Posted smallhester
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-2795 Billboard(线段树)相关的知识,希望对你有一定的参考价值。
题意:
有一块h*w的矩形广告板,要往上面贴广告;
然后给n个1*wi的广告,要求把广告贴上去;
而且要求广告要尽量往上贴并且尽量靠左;
求第n个广告的所在的位置,不能贴则为-1;
算法思想:
利用线段树可以求区间的最大值;
将位置即h用来建树(h<=n,大了没有意义);
树中存储的为该位置还拥有的空间;
若左子树的最大值大于他,就查询左子树,否则查询右子树;
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cstdio> #include<queue> #include<vector> using namespace std; #define ll long long const int maxn = 2e5 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; int st[(maxn<<2) + 5]; int h, w, n; void build(int o,int l,int r) { st[o] = w; if(l == r) return; int m = l + ((r-l) >> 1); build(o << 1,l,m); build((o<<1)|1,m+1,r); //st[o] = max(st[o << 1],st[(o<<1)|1]); } void pushup(int o){ st[o]=max(st[o<<1],st[o<<1|1]); } int query(int o,int l,int r,int ans) { if(l == r) { st[o] -= ans; return l; } int m = l + ((r-l)>>1); int res; if(st[o<<1] >= ans) res = query(o<<1,l,m,ans); else res = query((o<<1)|1,m+1,r,ans); pushup(o); return res; } int main() { while(~scanf("%d%d%d", &h, &w, &n)) { if (h > n) h = n; build(1, 1, h); while (n--) { int x; scanf("%d", &x); if (st[1] < x) printf("-1 "); else { printf("%d ", query(1, 1, h, x)); } } } }
以上是关于hdu-2795 Billboard(线段树)的主要内容,如果未能解决你的问题,请参考以下文章