zoukankan      html  css  js  c++  java
  • P4198 楼房重建

    传送门

    很妙的思路

    首先,我们可以把每一栋楼房转化为它的顶部到原点这条直线的斜率,这样就变成了从一个序列中选出一个最长上升子序列(其实不是最长上升子序列,不过可以这么理解)

    考虑用线段树来维护,对于每个区间,我们维护这个区间的最大值以及这个区间的答案,那么最后的答案就是(ans[1])

    对于叶节点来说,最大值就是它自己,答案为(1)

    考虑怎么合并区间。

    首先左边区间能看到的答案,当前区间必然也能看到

    考虑右边的区间。如果右区间的最大值小于等于左区间的最大值,那么一定会被挡住啥都看不见

    如果右区间的左区间的最大值小于等于左区间的最大值,左区间肯定会被挡住啥都看不见,那么我们就递归进右区间的右区间继续找答案

    如果右区间的左区间的最大值大于左区间的最大值,那么所有右区间的右区间里所有原来能看到的现在还是能看到。而左区间里继续递归找

    有点绕,建议看代码理解比较好

    总的复杂度为(O(nlog^2n))

    //minamoto
    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    using namespace std;
    #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<21],*p1=buf,*p2=buf;
    int read(){
        int res,f=1;char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(int x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int N=1e5+5;
    int n,m,ans[N<<2];double mx[N<<2];
    #define ls (p<<1)
    #define rs (p<<1|1)
    int query(int p,int l,int r,double sl){
    	if(mx[p]<=sl)return 0;if(l==r)return mx[p]>sl;
    	int mid=(l+r)>>1;
    	if(mx[ls]<=sl)return query(rs,mid+1,r,sl);
    	return query(ls,l,mid,sl)+ans[p]-ans[ls];
    }
    void upd(int p,int l,int r,int x,double sl){
    	if(l==r)return (void)(ans[p]=1,mx[p]=sl);
    	int mid=(l+r)>>1;
    	x<=mid?upd(ls,l,mid,x,sl):upd(rs,mid+1,r,x,sl);
    	mx[p]=max(mx[ls],mx[rs]);
    	ans[p]=ans[ls]+query(rs,mid+1,r,mx[ls]);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read();
    	while(m--){
    		int x=read(),y=read();
    		upd(1,1,n,x,1.0*y/x);
    		print(ans[1]);
    	}
    	return Ot(),0;
    }
    
  • 相关阅读:
    SQL时间戳的使用
    Java中利用MessageFormat对象实现类似C# string.Format方法格式化
    XML中PCDATA与CDATA的区别
    树行控件TreeView 在WinForm下 怎么实现重命名功能
    PHP+MySQL存储数据出现中文乱码的问题
    C#创建一个Windows Service
    SQL2008配置管理工具服务显示远程过程调用失败
    C#如何以管理员身份运行程序
    在APACHE服务器上的访问方式上去除index.php
    开发winform程序,在拖拽控件大小时,VS会卡死
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9957400.html
Copyright © 2011-2022 走看看