快速幂取模算法【模板】

快速幂取模其实是a^b%c,这就是著名的RSA公钥加密的方法,当a,b都很大的时候,直接求是不可取的,所以就用到了快速幂取模。

首先你得明白他的原理,其实是用到了二分的思想,把b按照二进制展开

b = p(n)*2^n  +  p(n-1)*2^(n-1)  +…+   p(1)*2  +  p(0)。其中p(i) (0<=i<=n)为 0 或 1。

所以此时a^b =  a^ (p(n)*2^n  +  p(n-1)*2^(n-1)  +...+  p(1)*2  +  p(0))=  a^(p(n)*2^n)  *  a^(p(n-1)*2^(n-1))  *...*  a^(p(1)*2)  *  a^p(0);

对于p(i)=0的情况不用处理,因为a^(p(i) * 2^(i-1) ) =  a^0  =  1;

所以我们需要考虑的仅仅是p(i)=1的情况,化简得:

a^(2^i)  = a^(2^(i-1)  * 2) = (  a^(  p(i)  *  2^(i-1)  )  )^2

http://baike.baidu.com/view/1431260.htm】此处有详细的介绍。

这里给出非递归的方法:

long long modexp(long long a, long long b, int mod)
{
    long long res=1;
    while(b>0)
    {
        //a=a%mod;(有时候n的值太大了会超出long long的储存,所以要先取余)
        if(b&1)//&位运算:判断二进制最后一位是0还是1,&的运算规则为前后都是1的时候才是1;
            res=res*a%mod;
        b=b>>1;//相当于除以2;
        a=a*a%mod;
    }
    return res;
}
时间: 2024-12-24 10:18:57

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

【转】C语言快速幂取模算法小结

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

快速幂取模算法

什么是快速幂? 快速幂应当是快速幂取模的简称 对于一般的求幂算法,求$a^b\,\bmod\,m$,即使用循环b次的方法,复杂度是$O(b)$的,当b很大的时候,这种算法就会显得十分缓慢. 快速幂是基于以下明显的事实: $${a^b} \equiv {(a^2)^{\frac{b}{2}}} \pmod{m}\quad b\ is\ even$$ $${a^b} \equiv {(a^2)^{\frac{b}{2}}*a} \pmod{m}\quad b\ is\ odd$$ 那么我们得到这样一

Raising Modulo Numbers_快速幂取模算法

Description People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games. Latest marketing research shows, that

【模板】快速幂取模

快速幂取模的模板,要注意所有变量都要开成long long类型的防溢出: #include<cstdio> #include<algorithm> #include<cstring> typedef long long LL; const LL mod=1e9+7; using namespace std; LL a,b; LL mi(LL x,LL y) { LL res=1; while(y){ if(y&1) res=res*x%mod; y>>

快速幂取模和快乘取模

一.快速幂取模概念 快速幂取模,顾名思义,就是快速的求一个幂式的模(余),比如a^b%c,快速的计算出这个式子的值. 在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法. 二.快速幂取模算法实现 1)很容易能想到,循环b次,每次乘a,最后对c取余就可以了. int ans = 1; for(int i = 1; i<=b; i++) { ans = ans * a; } ans = ans % c; 这个朴素算法的问题是: 1.如果a和b

快速幂取余算法

下面是一个快速幂的介绍: 先贴一个秦九韶算法(Horner算法)的原理: 设有项的次函数 将前项提取公因子,得 再将括号内的前项提取公因子,得 如此反复提取公因子,最后将函数化为 令 ...... 则即为所求 下面是讲解快速幂的:(By  夜せ︱深   感谢作者) 快速幂取模算法 在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~ 所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求

模板 快速幂取模

[模板]快速幂取模 1 long long quickmod(long long a,long long b,long long m) 2 { 3 long long ans = 1; 4 while(b)//用一个循环从右到左便利b的所有二进制位 5 { 6 if(b&1)//判断此时b[i]的二进制位是否为1 7 { 8 ans = (ans*a)%m;//乘到结果上,这里a是a^(2^i)%m 9 b--;//把该为变0 10 } 11 b/=2; 12 a = a*a%m; 13 } 1

快速幂取模(POJ 1995)

http://poj.org/problem?id=1995 以这道题来分析一下快速幂取模 a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 利用公式a*b%c=((a%c)*b)%c 每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化 由此可以用快速幂算法优化: http://www.cnblogs.com/qlky/p/5020402.html 再结合取模公式: (a + b) % p = (a % p

快速幂及快速幂取模

快速幂顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高.——bybaidu 快速幂可以用位运算这个强大的工具实现. 代码: 1 int pow(int a,int b) 2 { 3 int ans=1; 4 while(b!=0) 5 { 6 if(b&1) 7 ans*=a; 8 a*=a; 9 b>>=1; 10 } 11 return ans; 12 } 快速幂取模需要记住一个定理:积的取模等于取模积的取模:算法是蒙