hdu 2795(线段树)

来源:互联网 发布:vue.js有哪些ui框架 编辑:程序博客网 时间:2024/04/28 10:30

题目链接:点击打开链接

题目大意:有一块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;}

0 0
原创粉丝点击