P1226 快速幂||取余运算

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

题目描述

给你三个整数 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 ^3020+121+022+123
得到,我们通过思考将其和我们的幂的运算进行结合,便可得到一下式子:
3(0∗20+1∗21+0∗22+1∗23)3^ {(0 * 2^ 0 + 1 * 2^ 1 + 0 * 2^ 2 + 1 * 2^ 3)}3(020+121+022+123)

这时我们发现循环次数减少了一半多,指数系数为0可以不运算。最终我们可以得到以下式子:
3(21+23)3^ {(2^ 1+2^3)}3(21+23)=321∗3233^{2^1}*3^{2^3}321323
同底数密相乘,底数不变,指数相加

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(ab)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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值