基本算法---位运算---快速幂

∥☆過路亽.° 提交于 2019-11-28 11:15:19

快速幂的实现

洛谷P1226

题目描述

输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。

输入格式

三个整数b,p,k.

输出格式

输出“b^p mod k=s”

s为运算结果

输入输出样例

输入
2 10 9
输出
2^10 mod 9=7
 
一道位运算入门经典题,几乎所有讲算法的书籍都有所提及,此处就依照李煜东《算法竞赛————进阶指南》书中指导进行介绍。
 
考虑如下:
对于正整数b,一定可以唯一表示为若干指数不重复的2的次幂的和。
因此,不妨设b在二进制下有k位,其中第i(0<=i<k)位的数字是ci(ci=0或1),那么有:
b=ck-1*2k-1+ck-2*2k-2+…+c0*20
则必有:
ab=a^(ck-1*2k-1)*a^(ck-2*2k-2)*…*a^(c0*20)
(请参考书中式子,避免误解)
k=[log2(b+1)](向上取整),故上式乘积项不多于[log2(b+1)]
所以仅需求出上式的每一项mod p的值
通过a^2i=(a^(2i-1))2每一次不断改变a的值使其变为两倍,及b>>1向右不断移位,并判断b的最末尾是否是1,达到快速取模运算的效果
实际上,该算法时间复杂度应为O(log2n)。
#include<iostream>
#include<cstdio>
using namespace std;
int power(int a,int b,int p){
    int ans=1%p;
    while(b>0){
        if(b&1)ans=(long long)ans*a%p;
               //b&1可以取出b在二进制下最低位
        b>>=1;//移位,比b/2快
        a=(long long)a*a%p;//改变数值
    }
    return ans;
}
int main(){
    int a,b,p;
    scanf("%d%d%d",&a,&b,&p);
    printf("%d^%d mod %d=%d\n",a,b,p,power(a,b,p));
    return 0;
}
快速幂模板

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!