Solution
如果
b
a
s
e
base
base是偶数,那么
a
.
.
.
.
.
.
.
.
.
a
a
a
(
>
64
a.........aaa(>64
a.........aaa(>64个
a
)
a)
a)与
b
a
.
.
.
.
.
.
.
a
a
(
a
ba.......aa(a
ba.......aa(a的数量为前面那么串
a
a
a的数量
−
1
)
-1)
−1),这两个串长度相同,
h
a
s
h
hash
hash值相同,显然串是不同的,这样就卡掉了。
如果
b
a
s
e
base
base是奇数,就比较麻烦了。
看
v
f
k
vfk
vfk的做法吧:
如果
b
a
s
e
base
base是奇数的话,现在只考虑
a
a
a、
b
b
b两个字母。
a
∣
b
a|b
a∣b表示
a
a
a能整除
b
b
b。(
o
r
z
orz
orz具体数学)
设数学上的函数
n
o
t
(
S
)
not(S)
not(S)表示把字符串
S
S
S中每个位置的
′
a
′
'a'
′a′变成
′
b
′
'b'
′b′,把
′
b
′
'b'
′b′变成
′
a
′
'a'
′a′后形成的字符串。
s
t
r
A
.
s
t
r
B
strA.strB
strA.strB代表字符串串联。
∣
s
t
r
∣
|str|
∣str∣表示字符串
s
t
r
str
str的长度。
设字符串序列
o
r
z
s
t
r
[
i
]
{orzstr[i]}
orzstr[i],
o
r
z
s
t
r
[
1
]
=
"
a
"
,
o
r
z
s
t
r
[
i
]
=
o
r
z
s
t
r
[
i
−
1
]
.
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
orzstr[1]="a",orzstr[i]=orzstr[i-1].not(orzstr[i-1])
orzstr[1]="a",orzstr[i]=orzstr[i−1].not(orzstr[i−1])
那么
∣
o
r
z
s
t
r
[
i
]
∣
=
∣
o
r
z
s
t
r
[
i
−
1
]
∣
∗
2
|orzstr[i]|=|orzstr[i-1]|*2
∣orzstr[i]∣=∣orzstr[i−1]∣∗2。显然这是等比数列,得到:
∣
o
r
z
s
t
r
[
i
]
∣
=
∣
o
r
z
s
t
r
[
1
]
∣
.
2
i
−
1
=
2
i
−
1
|orzstr[i]|=|orzstr[1]|.2^{i-1}=2^{i-1}
∣orzstr[i]∣=∣orzstr[1]∣.2i−1=2i−1
设
h
a
s
h
(
s
t
r
)
hash(str)
hash(str)为
s
t
r
str
str的哈希值。
则:
h
a
s
h
(
o
r
z
s
t
r
[
i
]
)
=
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
∗
b
a
s
e
∣
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
∣
+
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
hash(orzstr[i])=hash(orzstr[i-1])*base^|not(orzstr[i-1])|+hash(not(orzstr[i-1]))
hash(orzstr[i])=hash(orzstr[i−1])∗base∣not(orzstr[i−1])∣+hash(not(orzstr[i−1]))
=
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
∗
b
a
s
e
2
i
−
2
+
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
=hash(orzstr[i-1])*base^{2^{i-2}}+hash(not(orzstr[i-1]))
=hash(orzstr[i−1])∗base2i−2+hash(not(orzstr[i−1]))
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
]
)
)
=
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
∗
b
a
s
e
2
i
−
2
+
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
hash(not(orzstr[i]))=hash(not(orzstr[i-1]))*base^{2^{i-2}}+hash(orzstr[i-1])
hash(not(orzstr[i]))=hash(not(orzstr[i−1]))∗base2i−2+hash(orzstr[i−1])
两式相减:
h
a
s
h
(
o
r
z
s
t
r
[
i
]
)
−
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
]
)
)
hash(orzstr[i])-hash(not(orzstr[i]))
hash(orzstr[i])−hash(not(orzstr[i]))
=
(
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
∗
b
a
s
e
2
i
−
2
+
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
)
−
(
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
∗
b
a
s
e
2
i
−
2
+
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
)
=(hash(orzstr[i-1])*base^{2^{i-2}}+hash(not(orzstr[i-1])))-(hash(not(orzstr[i-1]))*base^{2^{i-2}}+hash(orzstr[i-1]))
=(hash(orzstr[i−1])∗base2i−2+hash(not(orzstr[i−1])))−(hash(not(orzstr[i−1]))∗base2i−2+hash(orzstr[i−1]))
=
(
h
a
s
h
(
o
r
z
s
t
r
[
i
−
1
]
)
−
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
−
1
]
)
)
)
∗
(
b
a
s
e
2
i
−
2
−
1
)
=(hash(orzstr[i-1])-hash(not(orzstr[i-1])))*(base^{2^{i-2}}-1)
=(hash(orzstr[i−1])−hash(not(orzstr[i−1])))∗(base2i−2−1)
这让我们发现,
h
a
s
h
(
o
r
z
s
t
r
[
i
]
)
−
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
]
)
)
hash(orzstr[i])-hash(not(orzstr[i]))
hash(orzstr[i])−hash(not(orzstr[i]))似乎是个神奇的东西。而我们的目的实际上是要找两个字符串
s
t
r
A
,
s
t
r
B
strA,strB
strA,strB使得
h
a
s
h
(
s
t
r
A
)
=
h
a
s
h
(
s
t
r
B
)
(
m
o
d
(
2
64
)
)
hash(strA)=hash(strB)(mod(2^{64}))
hash(strA)=hash(strB)(mod(264))
相当与
2
64
∣
[
h
a
s
h
(
s
t
r
A
)
−
h
a
s
h
(
s
t
r
B
)
]
2^{64}|[hash(strA)-hash(strB)]
264∣[hash(strA)−hash(strB)]
设数列
f
[
i
]
{f[i]}
f[i],
f
[
i
]
=
h
a
s
h
(
o
r
z
s
t
r
[
i
]
)
−
h
a
s
h
(
n
o
t
(
o
r
z
s
t
r
[
i
]
)
)
f[i]=hash(orzstr[i])-hash(not(orzstr[i]))
f[i]=hash(orzstr[i])−hash(not(orzstr[i]))
这样就有:
f
[
i
]
=
f
[
i
−
1
]
∗
(
b
a
s
e
2
i
−
2
−
1
)
f[i]=f[i-1]*(base^{2^{i-2}}-1)
f[i]=f[i−1]∗(base2i−2−1)
还是有点不爽啊……我们再设数列
g
[
i
]
{g[i]}
g[i],
g
[
i
]
=
b
a
s
e
2
i
−
1
−
1
g[i]=base^{2^{i-1}}-1
g[i]=base2i−1−1
于是能写成:
f
[
i
]
=
f
[
i
−
1
]
∗
g
[
i
−
1
]
f[i]=f[i-1]*g[i-1]
f[i]=f[i−1]∗g[i−1]
则
f
[
i
]
=
f
[
1
]
∗
g
[
1
]
∗
g
[
2
]
∗
.
.
.
∗
g
[
i
−
1
]
f[i]=f[1]*g[1]*g[2]*...*g[i-1]
f[i]=f[1]∗g[1]∗g[2]∗...∗g[i−1]
然后发现一个神奇的事情?
b
a
s
e
base
base是奇数,则
b
a
s
e
base
base的任意正整数次方也一定是奇数。所以对于任意的
i
i
i必有
g
[
i
]
g[i]
g[i]为偶数,所以
2
i
−
1
∣
f
[
i
]
2^{i-1}|f[i]
2i−1∣f[i]
问题是不是结束了呢……发现没有……这样的话我们要使
2
64
∣
f
[
i
]
2^{64}|f[i]
264∣f[i],至少得让
i
=
65
i=65
i=65……然后发现
∣
o
r
z
s
t
r
[
65
]
∣
|orzstr[65]|
∣orzstr[65]∣是个天文数字。
发现我们刚才那样分析太坑爹了……
i
>
1
i>1
i>1时有:
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
−
1
]
∗
g[i]=base^{2^{i-1}}-1=(base^{2^{i-2}}-1)*(base^{2^{i-2}}+1)=g[i-1]*
g[i]=base2i−1−1=(base2i−2−1)∗(base2i−2+1)=g[i−1]∗一个偶数
而
g
[
1
]
g[1]
g[1]显然是偶数吧……
那么
4
∣
g
[
2
]
4|g[2]
4∣g[2],
8
∣
g
[
3
]
.
.
.
8|g[3]...
8∣g[3]...
也就是说
2
i
∣
g
[
i
]
2^i|g[i]
2i∣g[i]
所以
f
[
i
]
f[i]
f[i]实际上有:
(
2
1
)
∗
(
2
2
)
∗
(
2
3
)
∗
.
.
.
∗
(
2
i
−
1
)
∣
f
[
i
]
(2^1)*(2^2)*(2^3)*...*(2^{i-1})|f[i]
(21)∗(22)∗(23)∗...∗(2i−1)∣f[i]
2
i
∗
(
i
−
1
)
/
2
∣
f
[
i
]
2^{i*(i-1)/2}|f[i]
2i∗(i−1)/2∣f[i]
当
i
i
i取
12
12
12时,就有
66
66
66个
2
2
2了哟!
这就是卡
b
a
s
e
base
base为奇数时的方法。
o
r
z
s
t
r
[
12
]
orzstr[12]
orzstr[12]和
n
o
t
(
o
r
z
s
t
r
[
12
]
)
not(orzstr[12])
not(orzstr[12])即为所求。
而读入中 b a s e base base既有奇数又有偶数,直接在奇数构造的字符串后面加 64 64 64个 a a a就可以了。
Code
#include<cstdio>
#include<cstring>
int i,now,j;
char s[1<<12];
int main(){
puts("2113 1024");
putchar(s[now=1]+97);
for (i=0;i<11;i++,now<<=1)
for (j=0;j<now;j++) putchar((s[now+j]=s[j]^1)+97);
for (i=0;i<65;i++) putchar('a');
}