zoukankan      html  css  js  c++  java
  • HDU 2795 Billboard 【线段树】

    题目链接
    Segment Tree, single-point update

    题意

    有一块h*w的告示板,要向上面贴一些广告,每张广告都想被贴得尽量靠顶端,然后再尽量靠左。现有n块尺寸分别是1*wi的广告(高度都为1)依次贴上去,问没张广告贴得位置。

    分析

    首先实际贴得行数肯定是min(h,n),开始没注意这个,被数据范围吓到了。然后这个问题只要记录每一行还剩下多少宽度,然后每贴一个广告就查找尽量靠左并且宽度大于等于它的。于是这就是一个单点更新的线段树,只不过查询的地方稍微改一下即可。

    AC代码

    //HDU 2795 Billboard
    //AC 2016-10-16 15:13:32
    //Segment tree
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define lowbit(x) x&(-x)
    #define input(x) scanf("%d",&(x))
    #define inputt(x,y) scanf("%d %d",&(x),&(y))
    #define bug cout<<"here"<<endl;
    //#pragma comment(linker, "/STACK:1024000000,1024000000")//stack expansion
    //#define debug
    const double PI=acos(-1.0);
    const int INF=0x3f3f3f3f;//1061109567-2147483647
    const long long LINF=0x3f3f3f3f3f3f3f3f;//4557430888798830399-9223372036854775807
    const int maxn=200000+100;
    
    int h,w,n;
    
    /* 线段树 */
    struct segNode
    {
        int left,right;//结点对应的区间端点
        /*结点的性质*/
        int remain;
    };
    
    struct segTree
    {
        segNode tree[maxn*3+10];
        /* 线段树构造函数 */
        void build(int x,int left,int right)
        {
            tree[x].left=left;
            tree[x].right=right;
            if(left==right)//只有一个元素时
            {
                tree[x].remain=w;//储存单个元素的性质
                return;
            }
            /*递归构造子树*/
            int mid=(left+right)>>1;
            build(x<<1,left,mid);
            build(x<<1|1,mid+1,right);
            /* 回溯更新当前结点依赖于子节点的性质 */
            tree[x].remain=w;
            return;
        }
        /* 线段树区间查询 */
        int querry(int x,int v)
        {
            if(tree[x].remain<v)
                return -1;
            if(tree[x].left==tree[x].right)
                return tree[x].left;
            if(tree[x<<1].remain>=v)
                return querry(x<<1,v);
            else if(tree[x<<1|1].remain>=v)
                return querry(x<<1|1,v);
    
        }
        /* 单点更新 */
        void change(int x,int pos,int v)
        {
            if(tree[x].left==pos&&tree[x].right==pos)//找到这个点
            {
                /* 更新内容 */
                tree[x].remain-=v;
                return;
            }
            int mid=(tree[x].left+tree[x].right)>>1;
            if(pos<=mid)
                change(x<<1,pos,v);
            else
                change(x<<1|1,pos,v);
            /* 回溯更新 */
            tree[x].remain=max(tree[x<<1].remain,tree[x<<1|1].remain);
            return;
        }
    }billboard;
    
    
    
    int main()
    {
        //ios::sync_with_stdio(false);
        //cin.tie(0);
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        //IO
        while(scanf("%d %d %d",&h,&w,&n)!=EOF)
        {
            int N=min(h,n);
            billboard.build(1,1,N);
            int ads=0,pos=0;
            while(n--)
            {
                input(ads);
                pos=billboard.querry(1,ads);
                printf("%d
    ",pos);
                if(pos!=-1)
                    billboard.change(1,pos,ads);
            }
        }
        return 0;
    }
  • 相关阅读:
    codevs 2632 非常好友
    codevs 1213 解的个数
    codevs 2751 军训分批
    codevs 1519 过路费
    codevs 1503 愚蠢的宠物
    codevs 2639 约会计划
    codevs 3369 膜拜
    codevs 3135 River Hopscotch
    数论模板
    JXOJ 9.7 NOIP 放松模拟赛 总结
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580588.html
Copyright © 2011-2022 走看看