Hash Killer IV(欧拉定理&逆元)

Hash Killer IV(欧拉定理&逆元)

前话:貌似网上没有做出 H a s h   K i l l e r   I I I Hash\ Killer\ III 的人,可能是因为 d o u b l e   h a s h double\ hash 的正确性很高,不然 d o u b l e   h a s h double\ hash 挂掉, h a s h hash 算法就彻底宣告 g g gg 了,看到有 I V IV 版本,就过来了,结果发现跟 H a s h   K i l l e r Hash\ Killer 半毛钱关系没有。

思路:多所有操作倒过来进行。

对于 1 , 3 , 5 1,3,5 操作。

e p : t = t + ( t < < 10 ) = t × ( 2 10 + 1 ) ep:t=t+(t<<10)=t\times (2^{10}+1) .

即: t = t × ( 2 i + 1 ) t=t\times (2^i+1) .

因此对于方程 ( 2 i + 1 ) x = t ( m o d 2 32 ) (2^i+1)x=t\pmod{2^{32}}

考虑欧拉定理: a φ ( n ) 1 ( m o d p ) , ( a , p a^{\varphi(n)}\equiv1\pmod{p},(a,p 互质)

即: a × a ( φ ( n ) 1 ) 1 ( m o d p ) a\times a^{(\varphi(n)-1)}\equiv1\pmod{p}

a a 的逆元 i n v a = a ( φ ( n ) 1 ) ( m o d p ) inv_a=a^{(\varphi(n)-1)}\pmod{p}

注: φ ( 2 32 ) = 2 32 2 31 = 2 31 \varphi(2^{32})=2^{32}-2^{31}=2^{31}

然后我们用 t × i n v ( 2 i + 1 ) ( m o d p ) = x t\times inv_{(2^i+1)}\pmod{p} =x

扫描二维码关注公众号,回复: 11402694 查看本文章

就可以得到 x x 了。

对于 2 , 4 2,4 操作。

因为 ( t > > i ) (t>>i) 对于前 i i 位是不会改变的,所以可以用前面的高位推得低位。

这里用了一个常见的公式: a b = c a c = b a\oplus b=c\rightarrow a\oplus 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;//(2^16+1)的逆元
		Xor(x,11);	
		x*=954437177u;//(2^3+1)的逆元 
		Xor(x,6);
		x*=3222273025u;//(2^10+1)的逆元 
		cout<<x<<'\n';
	} 
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107476864