快速幂取模算法

所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。我们先从简单的例子入手:求abmodc

算法1.直接设计这个算法:

int ans = 1;
for(int i = 1;i<=b;i++)
{
   ans = ans * a;
}
ans = ans % c;

缺点:这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。

我们先来看看第一个改进方案:在讲这个方案之前,要先看这样一个公式:amod c = (a mod c)mod c

于是不用思考的进行了改进:

算法2.改进算法:

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
   ans = ans * a;
}
ans = ans % c;

读者应该可以想到,既然某个因子取余之后相乘再取余保持余数不变,那么新算得的ans也可以进行取余,所以得到比较良好的改进版本。

算法3.进一步改进算法:

int ans = 1;
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
{
   ans = (ans * a) % c;//这里再取了一次余
}
ans = ans % c;

这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,所以,我们推出以下的快速幂算法。

算法4.快速幂算法:

快速幂算法依赖于以下明显的公式:

int PowerMod(int a, int b, int c)
{
    int ans = 1;
    a = a % c;
    while(b>0) {
        if(b % 2 = = 1)
        ans = (ans * a) % c;
        b = b/2;
        a = (a * a) % c;
    }
    return ans;
}

本算法的时间复杂度为O(logb),能在几乎所有的程序设计(竞赛)过程中通过,是目前最常用的算法之一。

时间: 2024-10-28 15:02:30

快速幂取模算法的相关文章

C语言快速幂取模算法小结_C 语言

本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余).在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法.我们先从简单的例子入手:求abmodc 算法1.直接设计这个算法: int ans = 1; for(int i = 1;i<=b;i++) { ans = ans * a; } ans = ans %

UVa 374 Big Mod:快速幂取模

374 - Big Mod Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=310 Calculate for large values of B, P, and M using an efficient algorithm. (That's right, t

C++快速幂与大数取模算法示例_C 语言

一.快速幂 其实就是求(a^b)% p ,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式: (a*b)%p=(a%p*b%p)%p . 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) { long long a1=a,t=1; while(b>0) { if(b&1) /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*(a1%p)%p; b/=2;

NYOJ 102(高次幂取模)

1.二分递归: 使用a*b(mod   n)=(a(mod   n)*b(mod   n))(mod   n)即可.    #include<stdio.h> /* 错误 long long fun(long long a,long long b,long long c) { long long temp; if(0==b) return 1; temp=fun(a,b/2,c); if(b&1) return temp*a%c; return temp; } */ /* AC lon

POJ2447 分解因数+扩展欧几里得+高次幂取模

昨天一天弄明白的pollard-rho启发式因数分解没想到今天就用上了 而且是一次过 感觉好有成就感  题目大意 给你N=P*Q 先把p q从N因数分解出来 得到具体的值 然后(p-1)*(q-1)=t 从而求出t的值 有了t的值 根据e*d(mod t)=1 求出e模t的逆元d 注意求出的逆元可能为负 然后求c^d%n 为m 就是 题目要求的值 这题的解题步骤如下 1根据pollard-rho启发式因数分解 把n分解成两个素数p q; 2(p-1)*(q-1)求出t的值 3通过扩展欧几里得 求

快速幂取余

#include <iostream> using namespace std; typedef long long LL; LL quickmod(LL a, LL b, LL c) { LL ans=1; a%=c; while(b) { if(b&1) ans=(ans*a)%c; b/=2; a=(a*a)%c; } return ans; } int main() { LL a,b,c; while(cin>>a>>b>>c) { LL a

HDOJ 1097(幂取模)

  //超时代码,需要o(logn)#include <stdio.h>int main(){ int m,n,i,ans=1; while (scanf("%d%d",&m,&n)!=EOF) { for (i=1;i<=n;i++) { ans*=m; ans%=10; } printf("%d\n",ans); }} #include<stdio.h>long pow_mod(int m, int n, int p

取模运算-求大神解答关于大数幂的运算和去模运算,谢谢!!c语言

问题描述 求大神解答关于大数幂的运算和去模运算,谢谢!!c语言 RT 比如说,2的10000000次方,我用double倒是可以算,但是如何去模呢... 2的10000000次方对1234567取模... 谢谢大神们! 解决方案 我记得以前在蓝桥杯上做过这样的题,你可以使用一个for循环进行计算,然后在每次计算以后就用得数对1234567取模,然后再使用取模后的数继续进行 运算,这样就不会溢出了. 解决方案二: 快速幂取模,对数时间. //求a的b次方对x取余数 int powmod(int a

大整数取模(秦九韶算法)

//大整数取模,利用秦九韶算法 #include<stdio.h> #include<stdlib.h> #include<string.h> #define N 10000 int main() { char str[N]; int len;int i;int mod; long long ans=0; scanf("%s",str); getchar(); scanf("%d",&mod); len=strlen(st