BZOJ.3097 Hash Killer 1(卡掉自然溢出法)

BZOJ.3097 Hash Killer 1(卡掉自然溢出法)

题意:卡掉自然溢出法求不同长度为 L L 的字符串个数做法。

1.当 b a s e base 为偶数时,我们可以根据自然溢出法 m o d   2 64 mod\ 2^{64} 的原理,构造含 2 64 2^{64} h a s h hash 值。

如: 65 65 a h a s h = 0 a\rightarrow hash=0 ,一个 b b 后面 64 64 a b a s e 64 a\rightarrow base^{64}

因为 b a s e base 是偶数,所以 h a s h 2 = b a s e 64 % m o d = 0 = h a s h 1 hash_2=base^{64}\% mod=0=hash_1

2.当 b a s e base 为奇数时,根据 v F k vFk 巨佬的做法。

A [ 1 ] = a , n o t ( A [ i ] ) A[1]=a,not(A[i]) 表示将 A [ i ] A[i] 所有字母中的 a a 变成 b b b b 变成 a a

A [ i ] = A [ i 1 ] + n o t ( A [ i 1 ] ) A[i]=A[i-1]+not(A[i-1])

即: A [ 1 ] = a , A [ 2 ] = a b , A [ 3 ] = a b b a , A [ 4 ] = a b b a b a a b A[1]=a,A[2]=ab,A[3]=abba,A[4]=abbabaab\dots\dots

A [ i ] A[i] 的长度为 2 i 1 2^{i-1}

即: h a s h ( A [ i ] ) = h a s h ( A [ i 1 ] ) × b a s e 2 i 2 + h a s h ( n o t ( A [ i 1 ] ) ) hash(A[i])=hash(A[i-1])\times base^{2^{i-2}}+hash(not(A[i-1]))

令: f [ i ] = h a s h ( A [ i ] ) h a s h ( n o t ( A [ i ] ) ) f[i]=hash(A[i])-hash(not(A[i]))

可以推出: f [ i ] = f [ i 1 ] × ( b a s e 2 i 2 1 ) f[i]=f[i-1]\times(base^{2^{i-2}}-1)

g [ i ] = b a s e 2 i 1 1 g[i]=base^{2^{i-1}}-1

显然 g [ i ] g[i] 是偶数。

f [ i ] = f [ i 1 ] × g [ i 1 ] f[i]=f[i-1]\times g[i-1]

f [ i ] = f [ 1 ] × i = 1 i 1 g [ i ] f[i]=f[1]\times\prod\limits_{i=1}^{i-1}g[i]

即: 2 i 1 f [ i ] 2^{i-1}|f[i]

又: g [ i ] = b a s e 2 i 1 1 = ( b a s e 2 i 2 1 ) × ( b a s e 2 i 2 + 1 ) , g [ i ] = g [ i 1 ] × g[i]=base^{2^{i-1}}-1=(base^{2^{i-2}}-1)\times(base^{2^{i-2}}+1),g[i]=g[i-1]\times 偶数

所以 2 1 + 2 + 3 + i 1 f [ i ] 2 i ( i 1 ) 2 f [ i ] 2^{1+2+3\dots+i-1}|f[i]\rightarrow 2^{\small\dfrac{i(i-1)}{2}}|f[i]

即: i = 12 i=12 即可。

因为 f [ i ] = h a s h ( A [ i ] ) h a s h ( n o t ( A [ i ] ) ) f[i]=hash(A[i])-hash(not(A[i]))

说明 2 i ( i 1 ) 2 h a s h ( A [ i ] ) 2^{\small\dfrac{i(i-1)}{2}} |hash(A[i])

l e n = 2 i 1 = 2 11 len=2^{i-1}=2^{11}

n = 2 12 , l = 2 11 n=2^{12},l=2^{11}

并且在后面加 64 64 a a 也能卡掉偶数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=(1<<13)+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
char s[N];
int main(){
	int n=1;
	s[0]='a';
	for(int i=0;i<12;i++,n<<=1)
		for(int j=0;j<n;j++)
			s[j+n]=s[j]=='a'?'b':'a'; 
	printf("%d %d\n",n+64,n>>1);
	printf("%s",s);
	for(int i=0;i<64;i++) putchar('a');
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107457997