您的位置:首页 > 其它

洛谷之快速幂

2020-04-05 18:24 106 查看

这道题也是看了题解才明白的。感谢大神指点。
对幂的奇偶进行判断
假设我们拿到了 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<iostream>
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;
}

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

  • 点赞
  • 收藏
  • 分享
  • 文章举报
小熊迪帝 发布了12 篇原创文章 · 获赞 0 · 访问量 180 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: