为什么我的\(O(n)\)做法比\(O(nloglogn)\)做法跑得还慢啊!
首先S1的长度为\(i\)的子串有\(n-i+1\)个。
然后全部长度为\(i\)的子串有\(2^i\)个。
\(i\)成为答案长度的一个充分条件为\(2^i>n-i+1\)
带个\(i=log(n+1)\)进去发现成立。这启发我们将长度小于\(i\)的全部打出来然后看那个没有即可。
这样是\(O(nlogn)\)的。
我们考虑优化,发现一些子串都是前一个子串去掉最后一位,所以只要把所有最长的子串处理出来然后扔进数组里刷表即可。
时间复杂度\(O(n)\)
code:
#include<bits/stdc++.h> #include<set> #define I inline #define re register #define Me(x,y) memset(x,y,sizeof(x)) #define N 16777216 #define M 200000 #define W 25 #define db double #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define it iterator #define Gc() getchar() using namespace std; int n,m,k,now,F[N+5<<2],mod;char s[N+5],c; int main(){ freopen("c.in","r",stdin);freopen("c.out","w",stdout); re int i,j;c=Gc();while(c=='0'||c=='1') s[++n]=c,c=Gc();k=ceil(log2(n+1));mod=(1<<k)-1; for(i=1;i<=n;i++)now=(now<<1)+s[i]-48,now&=mod,F[(1<<min(i,k))+now]=1;for(now=0,i=1;i<=k;i++)now+=s[n-i+1]-'0'<<i-1,F[(1<<i)+now]=1; for(i=mod*2+1;i>1;i--)F[i>>1]|=F[i];for(i=2;i<=2*mod+1;i++){ if(!F[i]){for(now=i^(1<<(int)log2(i)),j=log2(i);j;j--) printf("%d",(now>>j-1)&1);return 0;} } }