zoukankan      html  css  js  c++  java
  • bzoj4149: [AMPPZ2014]Global Warming

    头都烂了怎么头疼啊

    考虑先做出对于一个位置以它作为唯一最小值的最远区间,这个可以单调栈上二分搞出来

    那么对于一个位置这个区间而言,一定是选择这个区间的最大数是作为最终的唯一最大数最优的

    为什么呢?我们可以把区间起止和区间之中的最大数下标弄出来,那么当前位置一定位于某两个弄出来的编号之间,其他数的答案不会大于这个区间大小,而假如是最大数除了包含这个区间以外还可以向一边拓展直到遇到下一个最大数

    那么二分找出这两个编号就好了,RMQ上个st表

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    
    #define qq(o,l,x) upper_bound(o+1,o+l+1,x)-o-1
    using namespace std;
    const int _=1e2;
    const int maxn=5*1e5+_;
    const int fbin=30;
    int n,a[maxn],lslen,ls[maxn];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    //--------------------------------------def------------------------------------------
    
    struct stack
    {
        int top,sta[maxn],d[maxn];
        stack(){}
        void clear(int k){top=0;}
        void push(int p,int x)
        {
            while(top>=1&&d[top]>=x)top--;
            sta[++top]=p;d[top]=x;
        }
        int findmner(int x){return sta[qq(d,top,a[x])];}
    };
    //~~~~~~~~stack~~~~~~~~~
    
    int Bin[fbin],Log[maxn],f[fbin][maxn],d[fbin][maxn];
    void initst()
    {
        Bin[0]=1;for(int i=1;i<=30;i++)Bin[i]=Bin[i-1]*2;
        Log[1]=0;for(int i=2;i<=n; i++)Log[i]=Log[i/2]+1;
        for(int i=1;i<=n;i++)f[0][i]=a[i];
        for(int j=1;Bin[j]<=n;j++)
            for(int i=1;i+Bin[j]-1<=n;i++)
                f[j][i]=max(f[j-1][i],f[j-1][i+Bin[j-1]]),
                d[j][i]=max(d[j-1][i],d[j-1][i+Bin[j-1]]);
    }
    int RMQ(int x,int y)
    {
        int k=Log[y-x+1];
        return max(f[k][x],f[k][y-Bin[k]+1]);
    }    
    //~~~~~~~~RMQ~~~~~~~~~~~
    
    //--------------------------------------data structure-----------------------------------------
    
    int mnL[maxn],mnR[maxn];//作为唯一最小的区间 
    stack up;vector<int>vec[maxn];
    int main()
    {
        freopen("26.in","r",stdin); 
        freopen("a.out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read(),ls[++lslen]=a[i];
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=n;i++)
        {
            a[i]=lower_bound(ls+1,ls+lslen+1,a[i])-ls;
            vec[a[i]].push_back(i);
        }    
        initst();
        
        up.clear(0),up.push(0,-(1<<30));
        for(int i=1;i<=n;i++)
            mnL[i]=up.findmner(i)+1,up.push(i,a[i]); 
        up.clear(0),up.push(n+1,-(1<<30));
        for(int i=n;i>=1;i--)
            mnR[i]=up.findmner(i)-1,up.push(i,a[i]);
        
        int ans=0,ll;
        for(int i=1;i<=n;i++)
        {
            int p=RMQ(mnL[i],mnR[i]);
            if(vec[p].front()<=i)
            {
                int u=upper_bound(vec[p].begin(),vec[p].end(),i)-vec[p].begin()-1;
                int L=mnL[i],R=mnR[i];
                if(u!=0)L=max(L,vec[p][u-1]+1);
                if(u!=vec[p].size()-1)R=min(R,vec[p][u+1]-1);
                
                if(R-L+1>ans || R-L+1==ans&&ll>L )ans=R-L+1,ll=L;
            }
            if(vec[p].back()>=i)
            {
                int u=lower_bound(vec[p].begin(),vec[p].end(),i)-vec[p].begin();
                int L=mnL[i],R=mnR[i];
                if(u!=0)L=max(L,vec[p][u-1]+1);
                if(u!=vec[p].size()-1)R=min(R,vec[p][u+1]-1);
            
                if(R-L+1>ans || R-L+1==ans&&ll>L )ans=R-L+1,ll=L;
            }
        }
        printf("%d %d
    ",ans,ll);
        
        return 0;
    }
  • 相关阅读:
    d3操作svg路径动画,及dom移动
    新时代前端必备神器 Snapjs之弹动效果
    threejs 鼠标移动控制模型旋转
    玩转SVG线条动画
    CSS也能计算:calc
    CSS两种盒子模型:cntent-box和border-box
    解决Jquery中click里面包含click事件,出现重复执行的问题
    区块链踩坑之基础扫盲及搭建以太坊网络私有链(单节点)
    微信朋友圈转发第三方网站带缩略图实现
    物流一站式查询之快递100篇
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10418429.html
Copyright © 2011-2022 走看看