取模運算相關的常數優化

2022-09-20 11:06:12 字數 1274 閱讀 2078

首先,若模數 \(p=2^,2^\),直接利用unsigned , unsigned long long自然溢位即可,方便而且快。

若 \(p\) 是其它 2 的整數次冪,可以通過位運算優化取模:用x&(p-1)代替x%p。(這種情況好像基本沒見過)

若 \(p\) 很小,例如 \(p=2022\) ,那麼可以放心地用int,少量取模保證不溢位即可。

大部分情況下,\(p\) 是乙個大質數(其實不是質數也沒關係),而且常見模數中最大的是 \(10^9+7\) 。

這時一次乘法就會有爆int的風險,但一次加減法不會。

仍然可以全程用int。例如當 \(0\le x,y時,

x=(x+y)%p;可寫成(x+=y)>=p&&(x-=p);

x=(x-y+p)%p;可寫成(x-=y)<0&&(x+=p);

避免了取模,也不會溢位

乘法可以寫x=1ll*x*y%p;,但這個未必比直接開long long然後(x*=y)%=p;

綜合下來也不知道是int好還是long long好。(

個人偏好int

如果優化加減法取模還不行的話,可以優化乘法取模

inline int mul(int x,int y,int p)
用了會快 雖然不知道為啥

還有乙個比較少見的技巧:預處理單位分數,優化除法

比如我們寫完一道題,簡單估算一下發現做了幾百萬次除法 \(x/y\)

然後我們發現 \(2\le y\le n=10^5\)

考慮如下操作:

...

const double eps=1e-14; // 乙個極小的常量

double inv[n+10];

inline int div(int x,int y)

...for (int i=2; i<=n; ++i) inv[i]=1./i+eps; // +eps 是為了防止精度損失

...

div(x,y)計算 x/y 。總體會快很多。

原理:浮點數乘法比整數除法快一點。

在特定場合下很有效。

除法的取模運算

逆元 若,b b1 c 1 則,b1稱為b模c的乘法逆元。在acm中,許多除法取模都要用到求逆元。但是,逆元,為什麼能給我們帶來 a b c a b1 c 當然a b要整除 要知道,取模等式等價變形中,是沒有除法的!而推導式,還是沒有用除法的地方!我們用反證法證明 若b b1 c 1,則 a b c...

取模運算的應用

有時候數非常大是可以考慮取模,多選擇一些模數提高正確率。取模運算可以理解為乙個雜湊雜湊函式,為了避免雜湊衝突,可以分別模不同的模數,如果每乙個模數都沒有產生雜湊衝突那麼就可以認為兩個數是相同的。判斷兩個數a,b是否相等,如果膜上10相等,膜上11相等。那麼有a k 110 b。110是10和11的最...

大數取模運算

問題分析 1 大數儲存 由於x的位數最大為400位,我們不能用現有的int,long,long long,double等資料型別進行儲存。一般儲存大數的方法是用乙個字串來表示。2 取模運算 模擬手算豎式的方法。用x從高到低的每一位加上前一位餘數 10來對bi進行 最後得到的結果就是x bi的結果。利...