HDU 2795 Billboard(线段树)

来源:互联网 发布:阿里云网站更改负责人 编辑:程序博客网 时间:2024/06/04 20:03

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2795

思路:用数的最下面的节点表示一层(即到最下面一层有n个节点就可以了),并且用这个节点的左或右的区间范围表示层数(子节点的左区间和右区间其实是相同的),这个思路很巧,我也是看了别人的题解才懂的

AC代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>const int inf = 0x3f3f3f3f;//1061109567typedef long long ll;const int maxn = 200010;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int value[maxn<<2];int h,w,n;void pushup(int rt){    value[rt] = max(value[rt<<1],value[rt<<1|1]);}void build(int l,int r,int rt){    value[rt] = w;    if(l == r) return;    int m = (r + l )>> 1;    build(lson);    build(rson);}int query(int x,int l,int r,int rt){    if(l == r)    {        value[rt] -= x;        return l;    }    int m = (l + r) >> 1;    int ret = (value[rt<<1] >= x) ? query(x,lson) : query(x,rson);    pushup(rt);    return ret;}int main(){    while(scanf("%d%d%d",&h,&w,&n) != EOF)    {        if(h > n) h = n;        build(1,n,1);        for(int i=0; i<n; i++)        {            int k;            scanf("%d",&k);            if(value[1] < k) printf("-1\n");            else printf("%d\n",query(k,1,h,1));        }    }    return 0;}



0 0