Hdu 2795

来源:互联网 发布:最近淘宝生意很差2017 编辑:程序博客网 时间:2024/05/18 15:28

【题意】

有h * w的黑板,其中有n个人要把1 * wi的报贴上去,贴的时候要满足尽量靠上&&靠左。

输出每次张贴位置的行号。

【解题思路】

线段树的区间为[1, h],树上节点代表所包含区间的最大宽度,初始化为w。

【AC代码】

#include <stdio.h>#include <string.h>#include <iostream>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int nn = 200010;int h,w,n,num;struct node{   int l,r;   int ms;}Tree[nn<<2];void Push_Up(int rt){    Tree[rt].ms = max(Tree[rt<<1].ms,Tree[rt<<1|1].ms);}void Build(int l,int r,int rt){    Tree[rt].l=l,Tree[rt].r=r;    Tree[rt].ms=w;    if(l==r)return ;    int m =(l+r)>>1;    Build(lson);    Build(rson);}void Update(int x,int rt){    if(Tree[rt].l==Tree[rt].r)    {        Tree[rt].ms-=x;        return ;    }    if(x<=Tree[rt<<1].ms)        Update(x,rt<<1);    else        Update(x,rt<<1|1);    Push_Up(rt);}void query_ans(int x,int rt){    if(Tree[rt].l==Tree[rt].r)    {        num = Tree[rt].l;        return ;    }    if(Tree[rt<<1].ms>=x)        query_ans(x,rt<<1);    else        query_ans(x,rt<<1|1);    Push_Up(rt);}int main(){    while(~scanf("%d%d%d",&h,&w,&n))    {        if(h>n) h =n;        Build(1,h,1);        while(n--)        {            int x;            scanf("%d",&x);            if(Tree[1].ms<x)puts("-1");            else            {                num = -1;                query_ans(x,1);                printf("%d\n",num);                Update(x,1);            }        }    }    return 0;}

0 0