题意:给你一个广告牌,然后上面能贴广告,每条广告占一行多列,给你广告牌的宽和高,给出很多广告让你输出它能贴在那一行(规则是上优先,然后左优先)
思路:线段树维护一下区间最大值,然后每次查找最左边的即可
ac代码:
using namespace std;
int w[N];
struct node{
int L,R;
int nmax;
};
node tree[N*4];
int n,c,m,x,a;
bool flag;
void build(int id,int L,int R){
tree[id].R=R;tree[id].L=L;
if(L==R)
{
tree[id].nmax=m;
return ;
}
build(id*2,L,(L+R)/2);
build(id*2+1,(L+R)/2+1,R);
tree[id].nmax=max(tree[id*2].nmax,tree[id*2+1].nmax);
}
void query(int id,int L,int R){
if(flag) return ;
if(tree[id].nmax<x)
{
cout<<-1<<endl;
return;
}
if(tree[id].L==tree[id].R)
{
cout<<tree[id].L<<endl;
flag=1;
tree[id].nmax-=x;
return ;
}
if(tree[id*2].nmax>=x)
query(id*2,L,(L+R)/2);
else
query(id*2+1,(L+R)/2+1,R);
tree[id].nmax=max(tree[id*2].nmax,tree[id*2+1].nmax);
}
int main(){
freopen("billboard.in","r",stdin);
freopen("billboard.out","w",stdout);
while(cin>>n>>m>>a)
{
n=min(200000,n);
build(1,1,n);
for(int i=1;i<=a;i++)
{
flag=0;
scanf("%d",&x);
query(1,1,n);
}
}
return 0;
}