2021 Un cierto valle y cierto plan prueba posterior # 4 T1

No hablaré del tema para evitar la infracción (aunque parece conmovido)

Personalmente creo que es un problema de pensamiento muy interesante. La
solución positiva es 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 = 0lo gn2In)=O ( n ) , aquí hay unO (n log ⁡ log ⁡ n) \ mathcal O (n \ log \ log n)O ( nlo glo gn ) método

En primer lugar, la respuesta a esta pregunta debe ser ≤ log ⁡ n + 1 \ le \ log n + 1lo gnorte+1
porque como máximo se puede encontrarnnen la cadena dadan longitudes diferentes son(log ⁡ n) + 1 (\ log n) +1( lo gn )+1 cuerda. Y porquen <2 (log ⁡ n) + 1 n <2 ^ {(\ log n) +1}norte<2( lo gn ) + 1 , entonces(log ⁡ n) + 1 (\ log n) +1( lo gn )+1 Debe ser una solución factible.

Entonces, solo necesitamos ≤ log ⁡ n \ le \ log nlo gSimplemente encuentre la respuesta dentro del rango de n

Entonces, también podemos encontrar que la respuesta es dicotómica.
Supongamos que se sabe que uno no aparece en la cadena original y la longitud es xxLa cadena de x . Luego, simplemente agregue un0/1 0/1al principio o al final de la cadena0 / 1 , se construye de una longitudx + 1 x + 1X+La cadena que satisface la condición de 1 puede retroceder de la misma manera, lo que demuestra la monotonicidad de la respuesta.
Por lo tanto, puede estar directamente enlog ⁡ n \ log nlo gDicotomías dentro del rango de n +O (n) \ mathcal O (n)O ( n ) cheque. Finalmente, después de encontrar la longitud de la respuesta, se puede usar el tiempo lineal para encontrar la cadena de respuesta con el orden lexicográfico más pequeño. Complejidad de tiempo totalO (n log ⁡ log ⁡ n) \ mathcal O (n \ log \ log n)O ( nlo glo gn )

#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;
}

Supongo que te gusta

Origin blog.csdn.net/Brian_Pan_/article/details/114033520
Recomendado
Clasificación