数论--快速幂取模

数论计算中经常出现的一种运算就是求一个数的幂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    {ba}


因此代码可写出:

下面采用分治法,例如,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;
}


你可能感兴趣的:(数论,ACM)