把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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;}
	}
}
posted @ 2021-07-09 06:27  275307894a  阅读(48)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end