HDU 2795 Billboard(线段树点更新)

来源:互联网 发布:socket() python 编辑:程序博客网 时间:2024/06/06 07:47

HDU 2795


题意:长条形广告(1*Wi),贴入广告板(h*w),尽可能的高,其次尽可能的左。


最初看到题,想到用数组记录入每一行剩余的长度,初始为w。
但是会发现每次都要从头扫描,直到找到符合的位置。时间复杂度,就不用谈了,一定T掉。


题目,又是不断更新某行的剩余长度,还要不断查询,所以线段树了。


知识点:选择范围的点更新。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#define MAXN 200001#define PI acos(-1.0)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define bug(a) cout<<"bug---->"<<a<<endl;using namespace std;typedef long long LL;LL h,w;int n;LL rlen[MAXN<<2];int ans;void pushup(int rt){    rlen[rt]=max(rlen[rt<<1],rlen[rt<<1|1]);}void build(int l,int r,int rt){    rlen[rt]=w;    if(l==r)        return;    int m=(l+r)>>1;    build(lson);    build(rson);}void update(LL clen,int l,int r,int rt){    if(rlen[rt]<clen) return;    if(l==r)    {        rlen[rt]-=clen;        ans=l;        return;    }    int m=(l+r)>>1;    if(clen<=rlen[rt<<1]) update(clen,lson);    else  update(clen,rson);    pushup(rt);}int main(){    while(scanf("%I64d%I64d%d",&h,&w,&n)!=EOF)    {        int N=n;        if(h<n)            n=h;        LL tw;        build(1,n,1);        for(int i=1;i<=N;i++)        {            scanf("%I64d",&tw);            ans=-1;            update(tw,1,n,1);            printf("%d\n",ans);        }    }    return 0;}



0 0
原创粉丝点击