HDU 2795 Billboard (线段树单点更新)

来源:互联网 发布:自动倍投软件 编辑:程序博客网 时间:2024/05/06 23:39

题意:有一块大小h*w的公告牌,可以在上面贴广告,每张广告大小为1*wi,优先贴在高处,左边,如果可以贴,输出贴在了第几排,否则输出-1

思路:线段树记录的是某个区间能张贴的最长广告长度,更新同时查询,可以张贴时:在l == r 的位置更新最底层的值,然后向上更新时取左右子区间的最大值


#include <stdio.h>#include <string.h>#define lson l, m, rt * 2#define rson m + 1, r, rt * 2 + 1using namespace std;int max[200010*4];void pushup(int rt){    max[rt] = max[rt * 2] > max[rt * 2 + 1] ? max[rt * 2] : max[rt * 2 + 1];}void build(int l, int r, int rt, int n){    if(l == r)    {        max[rt] = n;        return;    }    int m = (l + r) / 2;    build(lson, n);    build(rson, n);    pushup(rt);}int update(int w, int l, int r, int rt){    if(max[rt] < w) return -1;    if(l == r)    {        if(max[rt] >= w)        {            max[rt] -= w;            return l;        }        else        {            return -1;        }    }    int flag = -1, m = (l + r) / 2;    flag = update(w, lson); // 左半区间找到位置    if(flag < 0) //左半区间找不到位置        flag = update(w, rson);    pushup(rt);    return flag;}int main(){    #ifdef LOCAL    freopen("data.in", "r", stdin);    #endif    int r, c, n;    while(scanf("%d%d%d", &r, &c, &n) != EOF)    {        if(r > n) r = n;        build(1, r, 1, c);        while(n--)        {            int w;            scanf("%d", &w);            printf("%d\n", update(w, 1, r, 1));        }    }    return 0;}


0 0
原创粉丝点击