自然溢出哈希 hack 方法(转载)
https://www.cnblogs.com/tzcwk/p/hash-ull-hack.html
抄的别人的)
还有一个好玩的
1.base为偶数时,只要最后64位对应一样,那么两字符串的哈希值相同
\(f_i(s)=s[1]*base^{i-1}+s[2]*base^{i-2}+……+s[i]*base^0\)
会发现,在base的指数>=64后,对应的字符的哈希值一定能被\(2^{64}\)整除
2.base为奇数时,对于仅由a,b构成的字符串s,将\(\bar{s}\)定义为对字符串s进行取反(a变b,b变a),构造一个\(s_i=s_{i-1}+\overline{s_{i-1}}\)那么就会有
hash(\(s_i\))=hash(\(s_{i-1}\))*\(base^{2^{i-2}}\)+hash(\(\overline{s_{i-1}}\))
(多的那个二次方就是倍增成两倍产生的)
hash(\(\overline{s_i}\))=hash(\(\overline{s_{i-1}}\))*\(base^{2^{i-2}}\)+hash(\(s_{i-1}\))
两个式子一减,得
\(hash(s_i)-hash(\overline{s_i})=hash(s_{i-1})*(base^{2^{i-2}}-1)-hash(\overline{s_{i-1}})*(base^{2^{i-2}}-1)\)
记\(f_i=hash(s_i)-hash(\overline{s_i})\)
那么式子就变成了\(f_i=f_{i-1}*(base^{2^{i-2}}-1)\)
\(base^{2^{i}}-1=(base^{2^{i-1}}+1)*(base^{2^{i-2}}+1)*……*(base+1)*(base-1)\)
其中所有拆分出来的数均为偶数
所以\(2^{i+1}\mid{base^{2^{i}}-1}\)
(这里没看懂,有没有大佬解答一下)
于是
\(2^{i*(i-1)/2}\mid{f_i}\)
故对于i>=12,hash(\(s_i\))=hash(\(\overline{s_i}\))
顺带上hash killer 1
点击查看代码
#include<bits/stdc++.h>
using namespace std;
char s[100000];
string a="ab";
string b;
int cnt=0;
void fan(string a){
a+=b;cnt++;
int len=a.length();
for(int i=0;i<len;i++){
if(a[i]=='a') b+="b";
else if(a[i]=='b') b+="a";
}
if(cnt==13){
for(int i=0;i<a.length();i++){
cout<<a[i];
}
cout<<len<<endl;
cout<<endl;
}
}
int main(){
// for(int i=1;i<=15;i++){
// fan(a);
// }
}
关于蒲公英的话…………颓了,但在蓝书上看见了vector+二分查询的方法,有时间把俩都打一下