您的位置:首页 > 其它

hdu 2795(线段树)

2015-10-29 13:37 260 查看
题目链接:点击打开链接

题目大意:有一块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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: