0
点赞
收藏
分享

微信扫一扫

数论--快速幂取模


数论计算中经常出现的一种运算就是求一个数的幂ab对另外一个数n个模的运算,即计算:ab mod n (a,b,n是正整数)

由于计算机只能表示有限位的整数,所以编程时模取幂的运算要注意值的大小范围,当ab的值超过整数范围时,mod运算便无法进行。

如何解决这个问题,我们引出一个能计算ab mod n的值的有用算法——反复平方法,首先我们必须明确:

d=ab mod n=(…((((a mod n)*a)mod n)*a)mod n…*a)mod n    {共b个a}

因此代码可写出:

下面采用分治法,例如,a^29次方=a^14^2*a,而a^14=(a^7)^2,a^7=(a^3)^2*a;a^3=a^2*a,一共只做了7次乘法,不知有没有发现,上述递归方式和二分查找方法很类似--每次规模近似减小一半,因此时间复杂度为O(logn),比O(n)好了很多。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<string>
using namespace std;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
const int SIZE = 10000;
const int MOD = 5767169;
LL power_mod(LL a,LL b,LL mod)
{
LL ans=1;
for(a%=MOD; b; b>>=1,a=a*a%MOD)
{
if(b&1) ans=ans*a%MOD;
}
return ans;
}

或者也可以这样写:

int PowerMod(int a, int b, int c)
{
int ans = 1;
int k = a % c;
while(b>0)//(k*k % c)2^b %c
{
if(b % 2 == 1)//如果是奇数
ans = (ans * k) % c;
b = b/2;
k = (k * k) % c;//k是不断代入,以代表每一次降一次幂
}
return ans;
}




举报

相关推荐

0 条评论