• Luogu P4198 楼房重建 分块 or 线段树


    思路:分块

    提交:2次(第一次的求解有问题)

    题解:

    设块长为$T$,我们开$N/T$个单调栈,维护每一块的上升斜率。

    修改时暴力重构整个块,$O(T)$

    求解时记录一个最大斜率$lst$,然后块内二分,求出能看见几个,同时更新$lst$

    时间复杂度$O(N*(T+frac{N}{T}*log_2T)$,也不知道怎么算最小值,瞎猜$T=sqrt{N*log_2N}$(其实当时算了一下,现在发现算错了,就当是猜的吧$qwq$),后来试了试,定块长$1000$也可以。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    using namespace std;
    #define R register int
    #define ull unsigned long long
    #define ll long long
    #define pause (for(R i=1;i<=10000000000;++i))
    #define In freopen("NOIPAK++.in","r",stdin)
    #define Out freopen("out.out","w",stdout)
    namespace Fread {
    static char B[1<<15],*S=B,*D=B;
    #ifndef JACK
    #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
    #endif
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
    inline void gs(char* s) {
        register char ch; while(isempty(ch=getchar()));
        do *s++=ch; while(!isempty(ch=getchar()));
    }
    } using Fread::g; using Fread::gs;
    
    namespace Luitaryi {
    const int N=100010;
    int n,m,T;
    int pos[N],l[1300],r[1300];
    double a[N];
    struct STK {
        double stk[1300]; int top;
        inline int calc(double x) {
            R l=1,r=top+1;
            while(l<r) {
                R md=l+r>>1;
                if(stk[md]<=x) l=md+1; else r=md;
            } 
            return top+1-l;
        }
    }s[1300];
    inline void main() {
        n=g(),m=g(); T=sqrt(n*log2(n)); 
        for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1;
        for(R i=1,lim=pos[n];i<=lim;++i) l[i]=(i-1)*T+1;
        for(R i=1,lim=pos[n];i<lim;++i) r[i]=i*T; r[pos[n]]=min(pos[n]*T,n);
        while(m--) { R ans=0;
            R x=g(),y=g(); R p=pos[x]; 
            a[x]=1.0*y/x; s[p].top=0;
            for(R i=l[p],lim=r[p];i<=lim;++i) 
                s[p].stk[s[p].top]<a[i]?s[p].stk[++s[p].top]=a[i]:0;
            register double lst=0.0;
            for(R i=1;i<=pos[n];++i) 
                ans+=s[i].calc(lst),lst=max(lst,s[i].stk[s[i].top]);
            printf("%d
    ",ans);
        }
    }
    }
    signed main() {
        Luitaryi::main();
    }

    线段树的先咕着$QwQ$


    2019.07.20

  • 相关阅读:
    ZooKeeper 相关知识
    zookeeper 启动和停止脚本
    es 6.4.3 版本的es的处理方式
    SpringBoot启动使用elasticsearch启动异常:Received message from unsupported version:[2.0.0] minimal compatible
    windows下安装elasticsearch-6.4.3和elasticsearch-head插件
    二项式公式
    计算公式
    大规模数据如何检索?
    设计数据服务:为报表服务提供服务接口
    win10 桌面快捷键技术
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11217436.html
Copyright © 2020-2023  润新知