Hash Killer IV(欧拉定理&逆元)
前话:貌似网上没有做出
Hash Killer III的人,可能是因为
double hash 的正确性很高,不然
double hash挂掉,
hash算法就彻底宣告
gg了,看到有
IV版本,就过来了,结果发现跟
Hash Killer半毛钱关系没有。
思路:多所有操作倒过来进行。
对于
1,3,5操作。
ep:t=t+(t<<10)=t×(210+1).
即:
t=t×(2i+1).
因此对于方程
(2i+1)x=t(mod232)。
考虑欧拉定理:
aφ(n)≡1(modp),(a,p互质)
即:
a×a(φ(n)−1)≡1(modp)。
即
a的逆元
inva=a(φ(n)−1)(modp)
注:
φ(232)=232−231=231
然后我们用
t×inv(2i+1)(modp)=x
扫描二维码关注公众号,回复:
11402694 查看本文章
就可以得到
x了。
对于
2,4操作。
因为
(t>>i)对于前
i位是不会改变的,所以可以用前面的高位推得低位。
这里用了一个常见的公式:
a⊕b=c→a⊕c=b。
#include<bits/stdc++.h>
#define ui unsigned int
using namespace std;
void Xor(ui &x,ui y){
for(int i=31-y;~i;i--){
x^=((x>>(i+y)) & 1) << i;
}
}
int main()
{
int t;
cin>>t;
while(t--){
ui x;
cin>>x;
x*=4294901761u;
Xor(x,11);
x*=954437177u;
Xor(x,6);
x*=3222273025u;
cout<<x<<'\n';
}
}