ACM ICPC 2008–2009, NEERC, Northern Subregional Contest: B. Billboard

题目链接:

点击打开链接


B 题思路

查询 暴力 一定是会超时的,  所以肯定用树状数组或者 线段树进行 logn 级别的查询。

但是题目又想要求满足, 在满足的情况下尽可能的选择前面,  用线段树 维护, 得到的

就是答案;


【code】

#include <iostream>
#include <bits/stdc++.h>

#define lson rt<<1,l,mid
#define rson rt<<1|1,mid + 1,r

typedef long long ll;
const int MAXN=3e5+5;
const int INF=0x3f3f3f3f;
using namespace std;


ll add[MAXN<<2],sum[MAXN<<2];
int n;
int w,h,ans;
void PushUP(int rt)
{
    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}

void build(int rt,int l,int r)
{
    if(l==r)
    {
      //  sum[rt]=w;
        return ;
    }
    else
    {
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
        PushUP(rt);
    }
}

void update(int rt,int l,int r,int L,int R)
{
    //cout<<rt<<" "<<sum[rt]<<endl;
    if(sum[rt]<R || ans!=-1)
        return ;
    if(l==r)
    {
        sum[rt]-=R;
        ans=l;
        return ;
    }
    int mid=(l+r)>>1;
    update(lson,L,R);
    update(rson,L,R);
    PushUP(rt);
    return;
}
int main()
{
    freopen("billboard.in","r",stdin);
    freopen("billboard.out","w",stdout);

    cin>>h>>w>>n;
    for(int i=0;i<4*min(h,n);i++)
    {
        sum[i]=w;
    }

    build(1,1,min(h,n));
    for(int i=1;i<=n;i++)
    {
        ans=-1;
        int x;
        cin>>x;
        if(x<=w)
            update(1,1,min(h,n),i,x);
        cout<<ans<<endl;
    }
     fclose(stdin);
    fclose(stdout);
    return 0;
}

posted @ 2018-04-10 12:55  Sizaif  阅读(237)  评论(0编辑  收藏  举报