您的位置:首页 > 其它

HDU 2795 Billboard(线段树点更新)

2014-08-18 19:59 399 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: