• ACM: Billboard 解题报告-线段树


     Billboard
    Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Description

    在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w。所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等。。
     
    在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去。
     
    每张广告都是高度为1宽度为wi的细长的矩形纸条。
     
    贴广告的人总是会优先选择最上面的位置来帖,而且在所有最上面的可能位置中,他会选择最左面的位置,而且不能把已经贴好的广告盖住。

    如果没有合适的位置了,那么这张广告就不会被贴了。
     
    现在已知广告牌的尺寸和每张广告的尺寸,求每张广告被贴在的行编号。

    Input

    多组样例,不超过40个。
     
    对每组样例,第一行包含3个整数h,w,n(1 <= h,w <= 10^9; 1 <= n <= 200,000) -广告牌的尺寸和广告的个数。 

    下面n行每行一个整数 wi (1 <= wi <= 10^9) -  第i张广告的宽度.

    Output

    对每张广告,输出它被贴在的行编号(是1到h之间的数),顶部是第一行。如果某广告不能被贴上,则输出-1。

    Sample Input

    3 5 5
    2
    4
    3
    3
    3 

    Sample Output

    1
    2
    1
    3
    -1 

    1 //线段树专题
    2 //用父节点保存子节点剩余的最大的广告长度。 
    3 //AC代码如下:
     1 #include"iostream"
     2 #include"algorithm"
     3 #include"cstdio"
     4 #include"cstring"
     5 #include"cmath"
     6 #define max(a,b) a>b?a:b
     7 #define min(a,b) a<b?a:b
     8 #define lson l,m,rt<<1
     9 #define rson m+1,r,rt<<1|1
    10 using namespace std;
    11 
    12 const int  MX=300000+10;
    13 int sum[MX<<2];
    14 int h,w;
    15 
    16 void PushUp(int rt) {
    17     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);  //更新节点  父节点为子节点里面广告牌剩余的最大的长度
    18 }
    19 
    20 void Build(int l,int r,int rt) {
    21     sum[rt]=w;                //每个节点标记为广告纸的最大宽度
    22     if(r==l) return ;
    23     int    m=(r+l)>>1;
    24     Build(lson);
    25     Build(rson);
    26 }
    27 
    28 int Query(int x,int l,int r,int rt) {
    29     if(l==r) {
    30         sum[rt]-=x;         //查询到满足条件,更新此节点广告位置的长度
    31         return l;
    32     }
    33     int m=(r+l)>>1;
    34     int ret=0;
    35     if(sum[rt<<1]>=x) ret = Query(x,lson);  //从满足条件的广告剩余宽度开始粘贴
    36     else ret = Query(x,rson);            //总是从左节点开始贴广告纸
    37     PushUp(rt);
    38     return ret;
    39 }
    40 int main() {
    41     int n;
    42     int x;
    43     while(~scanf("%d%d%d",&h,&w,&n)) {
    44         h=min(h,n);            //【这样可以减少内存】多余的广告位不会使用到。 
    45         Build(1,h,1);        //总共的子节点数为广告牌的高度
    46         for(int qq=1; qq<=n; qq++) {
    47             scanf("%d",&x);
    48             if(sum[1]<x) printf("-1
    ");
    49             else printf("%d
    ",Query(x,1,h,1));
    50         }
    51     }
    52     return 0;
    53 }
    View Code
     
  • 相关阅读:
    对比git rm和rm的使用区别
    Gerrit日常维护记录
    [原创]Gerrit中文乱码问题解决方案分享
    MySQL 高可用架构
    MySQL 高可用架构
    Android L开发指南
    如何使用GOOGLE高级搜索技巧
    Linux定时关机
    Android源码批量下载及导入到Eclipse
    怎样将Android SDK源码 导入到Eclipse中?
  • 原文地址:https://www.cnblogs.com/HDMaxfun/p/5693303.html
Copyright © 2020-2023  润新知