P1226 快速幂||取余运算

17 篇文章 0 订阅

题目描述

给你三个整数 a,b,p求 a b a^b ab mod p p p

输入格式

输入只有一行三个整数,分别代表 a,b,pa,b,p。

输出格式

输出一行一个字符串 a b a^b ab mod p p p =s,其中 a,b,p 分别为题目给定的值, s为运算结果。

输入输出样例

输入

2 10 9

输出

2^10 mod 9=7
说明/提示
样例解释

2 10 2^{10} 210 = 1024
1024 mod 9 = 7

数据规模与约定

对于 100% 的数据,保证 0 < = a , b < 2 31 0<=a,b < 2^{31} 0<=a,b<231 ,a+b>0, 2 < = p < 2 31 2<=p< 2^{31} 2<=p<231

快速幂
快速幂算法是建立在二进制的按权展开求和的方法的基础上的,在二进制中我们先将二迸制的数写成加权系数展开式,而后根据十进制的加法规则进行求和得到原来的数,如10 二进制码为1010
可由
0 ∗ 2 0 + 1 ∗ 2 1 + 0 ∗ 2 2 + 1 ∗ 2 3 0 * 2^ 0+1 * 2 ^1 +0 * 2 ^2+1 * 2 ^3 020+121+022+123
得到,我们通过思考将其和我们的幂的运算进行结合,便可得到一下式子:
3 ( 0 ∗ 2 0 + 1 ∗ 2 1 + 0 ∗ 2 2 + 1 ∗ 2 3 ) 3^ {(0 * 2^ 0 + 1 * 2^ 1 + 0 * 2^ 2 + 1 * 2^ 3)} 3(020+121+022+123)

这时我们发现循环次数减少了一半多,指数系数为0可以不运算。最终我们可以得到以下式子:
3 ( 2 1 + 2 3 ) 3^ {(2^ 1+2^3)} 3(21+23)= 3 2 1 ∗ 3 2 3 3^{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 ) m o d    c = ( ( a m o d    c ) ∗ ( b m o d    c ) ) m o d    c (a * b) \mod c =((a \mod c)*(b \mod c)) \mod c (ab)modc=((amodc)(bmodc))modc
再而推导出后面公式:
( a b ) m o d    c = ( a m o d    c ) b m o d    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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值