大數冪的模運算
題目
我們知道對於像
7%2,3%5 這樣的題,計算機很容易算出它們的結果,但是如果我們需要計算7123456789%65536 這樣的值呢,這時普通的計算方式可能就要花費很久的時間了,有沒有簡單的方法可以算出來這類大數的模呢?
分析
假設我們有整數a, b與除數m ,那麼假設
a % m = j , b % m = t , 有整數 i , s , 使
a=im+jb=sm+t
所以有
a⋅b=(im+j)⋅(sm+t)=ism2+jsm+itm+jt
推出
(a⋅b)modm=(ism2+jsm+itm+jt)modm=jtmodm=((amodm)(bmodm))modm
所以
對於像7123456789%65536 這樣的大數冪模運算,我們可以把大數冪m拆分成形如m=m1+m2+...+mn 這樣的形式,那麼nm=nm1+m2+...+mn=nm1nm2⋅...nmn ,這樣通過上面的公式我們就可以很容易算出大數冪了.
因爲
abcmodm=((ab)⋅c)modm=(((ab)modm)(cmodm))modm=(((amodm)(bmodm)modm)(cmodm))modm
依次類推既可.我們再考慮大數冪m要如何分解成形如
m=m1+m2+...+mn 的形式.
觀察211=21+2+8=21×20+1×21+0×22+1×23 .
所以
可以把大數冪m寫成二進制,然後只取值爲1的位,和這一位在二進制中從右到左的位數(從0開始計算),就可以得到這個大數冪的分解式了.
代碼
// m爲底數,pow爲指數,n爲除數
int getMod(int m, int pow, int n)
{
int x = 1;
int power = m % n;
int mask = 1;
for(int i = 0; i < 32; i++) {
if((pow & mask) != 0) {
x = (x * power) % n;
}
power = (power * power) % n;
mask = mask << 1;
}
return x;
}
ps
如果計算