题目描述
给你三个整数 a,b,p求 aba^bab mod ppp
输入格式
输入只有一行三个整数,分别代表 a,b,pa,b,p。
输出格式
输出一行一个字符串 aba^bab mod ppp =s,其中 a,b,p 分别为题目给定的值, s为运算结果。
输入输出样例
输入
2 10 9
输出
2^10 mod 9=7
说明/提示
样例解释
2102^{10}210 = 1024
1024 mod 9 = 7
数据规模与约定
对于 100% 的数据,保证 0<=a,b<2310<=a,b < 2^{31}0<=a,b<231 ,a+b>0, 2<=p<2312<=p< 2^{31}2<=p<231
快速幂
快速幂算法是建立在二进制的按权展开求和的方法的基础上的,在二进制中我们先将二迸制的数写成加权系数展开式,而后根据十进制的加法规则进行求和得到原来的数,如10 二进制码为1010
可由
0∗20+1∗21+0∗22+1∗230 * 2^ 0+1 * 2 ^1 +0 * 2 ^2+1 * 2 ^30∗20+1∗21+0∗22+1∗23
得到,我们通过思考将其和我们的幂的运算进行结合,便可得到一下式子:
3(0∗20+1∗21+0∗22+1∗23)3^ {(0 * 2^ 0 + 1 * 2^ 1 + 0 * 2^ 2 + 1 * 2^ 3)}3(0∗20+1∗21+0∗22+1∗23)
这时我们发现循环次数减少了一半多,指数系数为0可以不运算。最终我们可以得到以下式子:
3(21+23)3^ {(2^ 1+2^3)}3(21+23)=321∗3233^{2^1}*3^{2^3}321∗323
同底数密相乘,底数不变,指数相加
int quick_pow(int a,int n)
{
int ans=1;
int base=a;
//n代表指数,对其一边进行二进制转化,一边计算
while (n>0)
{
//低位开始的二进制转化,如果此位当前是1
if(n%2==1)
ans=ans*base;
//每一位都进行一次乘积
base=base*base;
n=n/2;
}
return ans;
}
快速幂的模运算
(a∗b)mod c=((amod c)∗(bmod c))mod c(a * b) \mod c =((a \mod c)*(b \mod c)) \mod c(a∗b)modc=((amodc)∗(bmodc))modc
再而推导出后面公式:
(ab)mod c=(amod c)bmod c(a^b) \mod c =(a \mod c)^b \mod c(ab)modc=(amodc)bmodc
#include<bits/c++io.h>
#include<iostream>
#define ll long long
using namespace std;
ll quick_pow(ll a,ll n,ll mod)
{
ll ans=1,base=a%mod;
while (n>0)
{
if(n%2==1)
ans=(ans*base)%mod;
base=(base*base)%mod;
n=n/2;
}
ans=ans%mod;
return ans;
}
int main()
{
ll a,n,mod;
cin>>a>>n>>mod;
printf("%ld^%ld mod %ld=%ld",a,n,mod,quick_pow(a,n,mod));
return 0;
}

本文介绍了如何使用快速幂算法高效计算给定整数a、b和p的幂次方及其模运算aba^babmodppp。通过实例演示和代码实现,帮助理解并应用在实际问题中。
485

被折叠的 条评论
为什么被折叠?



