HDU 2795 Billboard

来源:互联网 发布:linux修改文件用户权限 编辑:程序博客网 时间:2024/06/06 18:38


思路: 我们可以将每一行当成一个叶子节点,起初叶子节点的均为w,此时我们便将问题转化为维护区间区间最大值即可,想通了之后便是一道简单的线段树单点更新的题目~~~


#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 222222;int max_item[MAXN<<2];int h, w, n, id;inline int min(int a, int b){    return a < b ? a : b;}inline int max(int a, int b){    return a > b ? a : b;}void Push_Up(int rt){    max_item[rt] = max(max_item[rt<<1], max_item[rt<<1|1]);}void bulid(int l, int r, int rt){    if(l == r)    {        max_item[rt] = w;        return;    }    int m = (l + r)>>1;    bulid(l, m, rt<<1);    bulid(m + 1, r, rt<<1|1);    Push_Up(rt);    return ;}void update(int val, int l, int r, int rt){    if(l == r)    {        max_item[rt] -= val;        id = l;        return ;    }    int m = (l + r)>>1;    if(max_item[rt<<1] >= val)        update(val, l, m, rt<<1);    else        update(val, m + 1, r, rt<<1|1);    Push_Up(rt);    return ;}int main(){    //freopen("aa.in", "r", stdin);    int t, t_w;    while(scanf("%d %d %d", &h, &w, &n) != EOF)    {        t = min(h, n);        bulid(1, t, 1);        for(int i = 1; i <= n; ++i)        {            scanf("%d", &t_w);            if(max_item[1] < t_w)                printf("-1\n");            else            {                update(t_w, 1, t, 1);                printf("%d\n", id);            }        }    }    return 0;}


原创粉丝点击