zoukankan      html  css  js  c++  java
  • P1114 “非常男女”计划

    题意:给你一个01串,求满足0和1总数相等的最大字串

         $n le 10^5$

    1、$O(n^3)$枚举起点终点,统计判断是否成立

    2、$O(n^2)$先$O(n)$时间计算01个数的前缀和,然后$O(1)$统计

    然而

    以上两种做法都会TLE

    不难发现,对于算法2,判断成立的条件是$sum1[j]-sum1[i]==sum0[j]-sum0[i]$

                                                   可以变个形$sum1[j]-sum0[j]==sum1[i]-sum0[i]$

                         我们令$cha[i]=sum1[i]-sum0[i]+n$(加n是为了防止出现负数)

                  那么现在,对于cha数组,我们只需要找出两个距离最远的相同数字就行了!

                  分别维护每个数字出现的最左和最右,$O(n)$取max

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int n;
    int ls[505000];
    int rs[505000];
    int su1[105000];
    int su2[105000];
    int cha[105000];
    int minn=0x7fffffff;
    int maxx;
    int main()
    {
        n=read();
        for(int x,i=1;i<=n;i++)
        {
            x=read();
            if(!x)
            {
                su1[i]=su1[i-1]+1;
                su2[i]=su2[i-1];
            }
            else
            {
                su1[i]=su1[i-1];
                su2[i]=su2[i-1]+1;
            }
            cha[i]=su1[i]-su2[i]+n;
        }
        memset(ls,0x6f,sizeof ls);
        for(int i=1;i<=n;i++)
        {
            ls[cha[i]]=min(ls[cha[i]],i);
            rs[cha[i]]=max(ls[cha[i]],i);
            minn=min(minn,cha[i]);
            maxx=max(maxx,cha[i]);
        } 
        int ans=0;
        for(int i=minn;i<=maxx;i++)
        {
            if(i==n)
                ans=max(ans,rs[i]);
            else
                ans=max(ans,rs[i]-ls[i]);
        }
        put(ans);
        olinr ~~(0^_^0)+love_nmr;
    }
  • 相关阅读:
    对《软件工程》这门课的总结
    结对编程项目---四则运算
    PSP记录个人项目耗时情况
    代码复审
    是否需要有代码规范
    四则运算的实现(C++)重做
    四则运算器的实现
    学习进度总结
    通过阅读教材,所得的不懂的问题
    自我介绍
  • 原文地址:https://www.cnblogs.com/olinr/p/9575142.html
Copyright © 2011-2022 走看看