O(1)快速乘
引用自2009年國家集訓隊論文,駱可強:《論程序底層優化的一些方法與技巧》
如果要求模的常數是一個64bit整數,那么在做乘法時,就沒有擴展類型使用,必須手寫一個高精度整數運算。
typedef long long ll; #define MOL 123456789012345LL inline ll mul_mod_ll(ll a,ll b) {ll d=(ll)floor(a*(long double)b/MOL+0.5);ll ret=a*b-d*MOL;if(ret<0) ret+=MOL;return ret; }首先,使用浮點數計算 a*b/MOL 的值,關鍵在于第二句,顯然? a*b -? d*MOL 兩個乘法都可能溢出,不過沒關系,因為可以預見,其差是一個64bit可以容納的正整數,那么溢出部分的差僅可能是0或者1。最后一句符號的特判用來處理溢出部分差為1的情況。
考慮到計算 a*b/MOL 使用了浮點數計算,誤差是不可避免的,故建議不要用太大的MOL使用這個方法。
模板
inline ll ksc(ll x,ll y,ll mod) {return (x*y-(ll)((long double)x/mod*y)*mod+mod)%mod; }因為x,y都是mod意義下的,保證了x*y/mod不會爆long long。
總結
- 上一篇: HDU 2255 奔小康赚大钱 带权二分
- 下一篇: 二分图的最大匹配 匈牙利算法