洛谷之快速幂

这道题也是看了题解才明白的。感谢大神指点。
对幂的奇偶进行判断
假设我们拿到了 x=3x = 3x=3,并且 p=11p = 11p=11。想求 3113^{11}311。·第一层循环。b=11b = 11b=11,一个奇数。将 3113^{11}311 分解为 31∗(32)53^1 * (32)531∗(32)5 来看。本层只需把 ans∗=31ans *= 3^1ans∗=31。那后面的呢?我们到下一层再搞定。下几层的总目标是让 ans∗=(32)5ans *= (32)5ans∗=(32)5,也就是让 ans∗=95ans = 9^5ans∗=95。来到下一层的方法是 x=3∗3=9x = 33 = 9x=3∗3=9 且 b=11/2=5b = 11 / 2 = 5b=11/2=5。·第二层循环几乎独立于第一层存在。b=5b = 5b=5,一个奇数。将 959^{5}95 分解为 91∗(92)29^1 * (92)291∗(92)2 来看。本层只需把 ans∗=91ans *= 9^1ans∗=91。那后面的呢?我们到下一层再搞定。下几层的总目标是让 ans∗=(92)2ans *= (92)2ans∗=(92)2,也就是让 ans∗=812ans = 81^2ans∗=812。于是 x=9∗9=81x = 99 = 81x=9∗9=81 且 b=5/2=2b = 5 / 2 = 2b=5/2=2。·第三层循环,b=2b = 2b=2,不是奇数,不着急,只把 81281^2812 当作 (812)1(812)1(812)1。下几层的总目标是让 ans∗=(812)1ans *= (812)1ans∗=(812)1。于是 x=81∗81=6561x = 81 * 81 = 6561x=81∗81=6561,b=2/2=1b = 2 / 2 = 1b=2/2=1。·第四层循环,b=1b = 1b=1,是奇数。这时候已经不用看成什么分解了,ans∗=6561ans *= 6561ans∗=6561 就可完成总目标。b/2b / 2b/2 为 000。结束循环。

#include
using namespace std;
int main(){
     
 long long x,x1,p,p1,m,result;
 cin>>x>>p>>m;
 x1=x;p1=p;
 if(p==0){
     
  cout<<x1<<'^'<<p1<<" mod "<<m<<"="<<1%m; return 0;
 }
 result=1;
 while(p){
     
  if(p%2==1) {
     result*=x;result%=m;} 
  p/=2;
  x=x*x;x%=m;
 }
      cout<<x1<<'^'<<p1<<" mod "<<m<<"="<<result;
 return 0;
}

这里好像还要考虑幂为零的情况。

还有一种是刚接触的位运算方式
1)如果将 aaa 自乘一次,就会变成 a2a^2a2 。再把 a2a^2a2 自乘一次就会变成 a4a^4a4 。然后是 a8a^8a8…… 自乘 nnn 次的结果是 a2na{2{n}}a2n 。对吧……(2)axay=ax+yaxay = a^{x+y}axay=ax+y,这个容易。(3)将 bbb 转化为二进制观看一下:比如 b=(11)10b = (11){10}b=(11)10​ 就是 (1011)2(1011){2}(1011)2​ 。从左到右,这些 111 分别代表十进制的 8,2,18,2,18,2,1。可以说 a11=a8×a2×a1a^{11} = a^8 × a^2 × a^1a11=a8×a2×a1。为什么要这样表示?因为在快速幂的过程中,我们会把 aaa 自乘为 a2a^2a2,然后 a2a^2a2 自乘为 a4a^4a4……像上面第一条说的。

while(b > 0)
    {
     
        if(b & 1)
        {
     
            ans *= base;
            ans %= m;
        }

        base *= base;
        base %= m;
        b >>= 1;
    }

边乘边取余并不影响结果。

你可能感兴趣的:(洛谷之快速幂)