自然溢出哈希 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+二分查询的方法,有时间把俩都打一下

posted @ 2024-04-26 15:56  shaoyufei  阅读(70)  评论(5编辑  收藏  举报