Problem B. Billboard

传送门

线段树 模板题,若该区间的最大值大于v,先去左子树,若不行,去右子树,找到,回来更新这棵树

这个题应该加上 h=min(h,n); 这条语句,若不加会runtime error on 18 

代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
const int N=200000+7;
int MAX[N<<2],w,v,ind;
void Push_up(int rt) {  MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); }
void Push(int rt)
{
    if(rt==1)   return;
    rt=rt>>1;
    Push_up(rt);
    Push(rt);
}
void query(int l,int r,int rt)
{
    if(l==r)
    {
        ind=l;
        MAX[rt]-=v;
        Push(rt);
        return;
    }
    int mid=(l+r)>>1;
    if(MAX[rt<<1]>=v)
        query(l,mid,rt<<1);
    else
        query(mid+1,r,rt<<1|1);
}
int main()
{
    int h,n;
    freopen("billboard.in","r",stdin);
    freopen("billboard.out","w",stdout);
    scanf("%d%d%d",&h,&w,&n);
    //map<int,int>my;
    h=min(h,n);
    for(int i=0;i<4*h;i++)
        MAX[i]=w;
    while(n--)
    {
        scanf("%d",&v);
        if(MAX[1]<v)
            printf("-1
");
        else
        {
            query(1,h,1);
            printf("%d
",ind);
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/lemon-jade/p/8779330.html