题目:http://www.gdfzoj.com/oj/contest/143/problems/5
李华是一名品学兼优、积极向上、热爱国家、热爱人民的优秀高中生。作为一名学生干部,他负责管理学生会的告示板。
告示板大小为h行,w列,各个学生社团有时会将高为1,长为L的告示贴到告示板上。当有人张贴告示时,李华会把告示张贴在空间足够的最高那一行的尽可能靠左的位置;如果空间不够,这张告示将不会被张贴。
给你告示板和各张告示的大小,请你帮助李华找到每张告示应张贴在哪一行
对于30%数据 n<=2000 数据组数<=40
对于60%数据 n<=20000 数据组数<=10
对于100%数据 n<=200000 数据组数 <=2
h,w<=10e9
一开始以为按h线段树,但10^9吓到我了。。。离散化居然不行。后来发现只用线段树 min(n,h) 即可,因为告示板不可能贴到大于n的行数。。。(看似有毒)
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct node
{
int l,r,rest;//
};
const int maxS=200000;
int h,w,n;
node M[4*maxS+5];
void pushup(int x)
{
M[x].rest=max(M[2*x].rest,M[2*x+1].rest);
}
void build(int x,int l,int r)
{
int mid=(l+r)/2;
M[x].l=l; M[x].r=r; M[x].rest=w;
if (l==r)
return ;
build(2*x,l,mid);
build(2*x+1,mid+1,r);
}
void update(int x,int len)
{
int mid=(M[x].l+M[x].r)/2;
if (M[x].l==M[x].r)
{
M[x].rest-=len;
printf("%d\n",M[x].l);
return ;
}
if (M[2*x].rest>=len)
update(2*x,len);
else if (M[2*x+1].rest>=len)
update(2*x+1,len);
else
{
printf("%d\n",-1);
// return ;
}
pushup(x);
}
int main()
{
int i,L;
freopen("a.txt","r",stdin);
freopen("b.txt","w",stdout);
while (scanf("%d%d%d",&h,&w,&n)!=EOF)
{
build(1,1,min(n,h));
for (i=1;i<=n;i++)
{
scanf("%d",&L);
update(1,L);
}
}
return 0;
}