1. 程式人生 > 實用技巧 >大數相乘的快速乘技巧

大數相乘的快速乘技巧

數論 大數相乘的快速乘技巧

1.1 問題

快速乘常用於解決如下問題:long long 與 long long 相乘,對long long 取模。顯而易見,結果有可能不在long long 範圍內,可能會溢位。因此,我們需要一種對該問題的有效解決方法

2.1 __int128

玄學資料型別,聯賽是肯定不能使用的,所以,棄療(≧∇≦)ノ

2.2 龜速乘

快速冪的思路在於二進位制優化一下乘法的過程,實現快速求冪;龜速乘的思路很接近,利用二進位制優化一下加法的過程,實現龜速乘法。long long 相加總不會爆long long 吧<( ̄ c ̄)y▂ξ

ll qsc(ll a,ll b,ll m){
	ll ans=0,base=a,mod=m;
	while(b){
		if(b&1) ans=(ans+base)%mod;
		base=(base+base)%mod;
		b>>=1;
	}
	return ans;
}

2.3 神奇小技巧

\[ull \Rightarrow unsigned long long \quad \quad \quad ld\Rightarrow long double \]

ll qsc(ll a,ll b,ll m){
    return ((ull)a*b-(ull)((ld)a/m*b*b))%m;
}

實際上就是把取模的過程分解了一下

\[a\times b \mod p\equiv a\times b -\lfloor \frac {a\times b}{p}\rfloor \times p \mod p \]

用一下long double處理一下分數,然後再利用unsigned long long 對\(2^{64}\)

智慧溢位,實現了這個O(1)快速乘。雖然看上去不靠譜,但實際實驗一下發現還的確是有正確性的。