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 = 0∑lo 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 + 1≤lo 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 n≤lo 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;
}