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;
    }
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/olinr/p/9575142.html
Copyright © 2011-2022 走看看