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=0∑logn2in)=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+1≤logn+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 n≤logJust 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;
}