BZOJ.3097 Hash Killer 1(卡掉自然溢出法)
题意:卡掉自然溢出法求不同长度为
L的字符串个数做法。
1.当
base为偶数时,我们可以根据自然溢出法
mod 264的原理,构造含
264的
hash值。
如:
65个
a→hash=0,一个
b后面
64个
a→base64。
因为
base是偶数,所以
hash2=base64%mod=0=hash1
2.当
base为奇数时,根据
vFk巨佬的做法。
令
A[1]=a,not(A[i])表示将
A[i]所有字母中的
a变成
b,
b变成
a。
且
A[i]=A[i−1]+not(A[i−1])。
即:
A[1]=a,A[2]=ab,A[3]=abba,A[4]=abbabaab……
A[i]的长度为
2i−1。
即:
hash(A[i])=hash(A[i−1])×base2i−2+hash(not(A[i−1]))
令:
f[i]=hash(A[i])−hash(not(A[i]))
可以推出:
f[i]=f[i−1]×(base2i−2−1)
令
g[i]=base2i−1−1。
显然
g[i]是偶数。
f[i]=f[i−1]×g[i−1]。
f[i]=f[1]×i=1∏i−1g[i]
即:
2i−1∣f[i]。
又:
g[i]=base2i−1−1=(base2i−2−1)×(base2i−2+1),g[i]=g[i−1]×偶数。
所以
21+2+3⋯+i−1∣f[i]→22i(i−1)∣f[i]。
即:
i=12即可。
因为
f[i]=hash(A[i])−hash(not(A[i]))
说明
22i(i−1)∣hash(A[i])。
len=2i−1=211
n=212,l=211
并且在后面加
64个
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;
}