hdu 2795 线段树,区间更新求补值

来源:互联网 发布:医美网络咨询师好做吗 编辑:程序博客网 时间:2024/05/21 01:57

题意:

给一个w*h的板子,代表长为w,高为h的长方形。

现在有n条1*x的小广告要往上面贴,贴的时候总是要选择高的地方并且靠左边的地方贴。

每给一个广告,问他贴在第几个w,若贴不上去,则输出-1。


解析:

把整个板子正转90°。

若h为5, w为3。

则:

3  |

    |

    |

       1          2            3          4          5


将1-5作为线段树去维护就行了。

每次取到最前的坐标。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 200000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int h, w, n;int sum[maxn << 2];void pushup(int rt){    sum[rt] = max(sum[rt << 1], sum[rt << 1 | 1]);}void build(int lo, int hi, int rt){    sum[rt] = w;    if (lo == hi)        return;    int mi = (lo + hi) >> 1;    build(lson);    build(rson);}int query(int x, int lo, int hi, int rt){    if (lo == hi)    {        sum[rt] -= x;        return lo;    }    int mi = (lo + hi) >> 1;    int res;    if (x <= sum[rt << 1])        res = query(x, lson);    else        res = query(x, rson);    pushup(rt);    return res;}int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);    #endif // LOCAL    while (~scanf("%d%d%d", &h, &w, &n))    {        if (n < h)            h = n;        build(1, h, 1);        while (n--)        {            int x;            scanf("%d", &x);            if (sum[1] < x)            {                printf("-1\n");            }            else            {                printf("%d\n", query(x, 1, h, 1));            }        }    }    return 0;}


0 0
原创粉丝点击