首页 > 其他 > 详细

【题解】Luogu P4198 楼房重建

时间:2019-02-02 21:30:21      阅读:210      评论:0      收藏:0      [点我收藏+]

原题传送门

根据斜率来建线段树,线段树维护区间最大斜率以及区间内能看见的楼房的数量(不考虑其他地方的原因,两个节点合并时再考虑)

细节见程序

#include <bits/stdc++.h>
#define db double 
#define N 100005
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline db Max(register db a,register db b)
{
    return a>b?a:b;
}
int n,m;
int ans[N<<3];
db maxx[N<<3];
inline int query(register int x,register int l,register int r,register db v)
{
    if(maxx[x]<=v)
        return 0;
    else if(l==r)
        return maxx[x]>v;
    else if(maxx[x<<1]<=v)
        return query(x<<1|1,(l+r>>1)+1,r,v);
    else
        return query(x<<1,l,l+r>>1,v)+ans[x]-ans[x<<1];
}
inline void update(register int x,register int l,register int r,register int pos,register db v)
{
    if(l==r)
    {
        ans[x]=1,maxx[x]=v;
        return;
    }
    int mid=l+r>>1;
    if(pos<=mid)
        update(x<<1,l,mid,pos,v);
    else
        update(x<<1|1,mid+1,r,pos,v);
    maxx[x]=Max(maxx[x<<1],maxx[x<<1|1]);
    ans[x]=ans[x<<1]+query(x<<1|1,mid+1,r,maxx[x<<1]);
}
int main()
{
    n=read(),m=read();
    while(m--)
    {
        int pos=read(),h=read();
        update(1,1,n,pos,(db)h/pos);
        write(ans[1]),puts("");
    }
    return 0;
}

【题解】Luogu P4198 楼房重建

原文:https://www.cnblogs.com/yzhang-rp-inf/p/10349148.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!