快速幂取模以及分治法幂取模

2019-04-13 20:57发布

long long qumo(long long a, long long b, long long m) { if(b == 0) return 1; int x = qumo(a,b/2,m); long long ans = (long long)x*x%m; if(b%2==1) ans=ans*a%m; return (int)ans; }//这是分治法;


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; //a的2的i次方 等于a的2的i-1次方的平方 把所有的a^2^i列举出来 } return res; }
//转换成二进制的做法
这个快速幂取模给出了很详细的解释,至于原理: 快速幂取模其实是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://blog.csdn.net/u013486414/article/details/42318931 再推荐一篇详细的文章 链接