2021 A certain Valley and certain plan later test #4 T1

I won’t talk about the subject to avoid infringement (although it seems to be moved)

Personally think it is a very interesting thinking problem. The
positive solution is O (∑ i = 0 log ⁡ nn 2 i) = O (n) \mathcal O(\sum\limits_{i=0)^{\log n}\frac{ n}{2^i})= \mathcal O(n)O (i=0logn2in)=O ( n ) , here is anO (n log ⁡ log ⁡ n) \mathcal O(n \log \log n)O ( nloglogn ) method

First of all, the answer to this question must be ≤ log ⁡ n + 1 \le \log n+1logn+1
because at mostnncan be found in the string givenn different lengths are(log ⁡ n) + 1 (\log n)+1(logn)+1 string. And becausen <2 (log ⁡ n) + 1 n<2^{(\log n)+1}n<2(logn ) + 1 , so(log ⁡ n) + 1 (\log n)+1(logn)+1 It must be a feasible solution.

Then, we only need to ≤ log ⁡ n \le \log nlogJust find the answer within the range of n

Then, we can also find that the answer is dichotomous.
Suppose it is known that one does not appear in the original string, and the length is xxThe string of x . Then, just add a0/1 0/1at the beginning or end of the string0 / 1 , it is constructed of a lengthx + 1 x + 1x+The string that satisfies the condition of 1 , can be pushed back in the same way, thus proving the monotonicity of the answer.
So, it can be directly inlog ⁡ n \log nlogDichotomies within the range of n +O (n) \mathcal O(n)O ( n ) check. Finally, after finding the length of the answer, linear time can be used to find the answer string with the smallest lexicographic order. Total time complexityO (n log ⁡ log ⁡ n) \mathcal O(n \log \log n)O ( nloglogn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int Maxn=16777216+20;
char s[Maxn];
bool a[Maxn];
int c[Maxn];
int n,m,cnt;
bool check(int len)
{
    
    
    int cur=0,ret=0;
    for(int i=1;i<=len;++i)
    cur=(cur<<1)|a[i];
    ++c[cur];
    if(c[cur]==1)++ret;
    for(int i=len+1;i<=n;++i)
    {
    
    
        cur^=(a[i-len]<<(len-1));
        cur=(cur<<1)|a[i];
        ++c[cur];
        if(c[cur]==1)++ret;
    }
    fill(c,c+1+(1<<len),0);
    if(ret==(1<<len))return 0;
    return 1;
}
int main()
{
    
    
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;++i)
    if(s[i]=='1')a[i]=1;
    if(n==1)
    {
    
    
        if(a[1])puts("0");
        else puts("1");
        return 0;
    }
    m=log2(n)+1;
    int l=1,r=m;
    while(l<r)
    {
    
    
        int mid=(l+r)>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    int len=l;
    int cur=0;
    for(int i=1;i<=len;++i)
    cur=(cur<<1)|a[i];
    c[cur]|=1;
    for(int i=len+1;i<=n;++i)
    {
    
    
        cur^=(a[i-len]<<(len-1));
        cur=(cur<<1)|a[i];
        c[cur]|=1;
    }
    for(int x=0;x<(1<<len);++x)
    if(!c[x])
    {
    
    
        for(int i=len-1;i>=0;--i)
        if((x>>i) & 1)putchar('1');
        else putchar('0');
        putchar('\n');
        return 0;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/Brian_Pan_/article/details/114033520