1. 程式人生 > 其它 >2019.7.8 義烏模擬賽 T3 C

2019.7.8 義烏模擬賽 T3 C

為什麼我的\(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;}
	}
}