ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P1226 【模板】快速幂||取余运算

2020-02-01 12:06:07  阅读:338  来源: 互联网

标签:b% return 17 洛谷 long P1226 cal 取余 mod


题目描述

给你三个整数 b,p,k 求 bp mod k的值。

输入格式

一行三个整数 b,p,k

输出格式

输出 bp mod k=s

s 为运算结果

输入输出样例

//输入
2 10 9
//输出
7
//2^10 mod 9=7

思路

显然,这道题可以用二分法

即可以将p进行拆解,举个栗子3^90 mod 17

3^90 mod 17= ((3^45 % 17)*(3^45 % 17)) % 17
而3^45 mod 17=((3^22 % 17)*(3^22 % 17)*(3 % 17)) % 17
后3^22 mod 17=((3^11 % 17)*(3^11 %17)) % 17

以此类推得

3^11 % 17 = ((3^5 % 17)*(3^5 %17)*(3 %17)) % 17
3^5 % 17 = ((3^2 % 17)*(3^2 % 17)*(3 % 17)) % 17
3^2 % 17= ((3 % 17)*(3 % 17)) % 17

因此可得如下p的变化

p p/2
90 45
45 22
22 11
11 5
5 2
2 1

为了提升速度,我们据上表,可知只需计算上表绿色部分,即3"绿色部分" % 17,得代码如下

long long cal(long long b,long long p,long long k) {
    if(p==1) return b%k;
    return ( cal( b , p/2 , k )%k * cal( b , p/2 , k )%k )%k;
}

为了处理当p出现奇数的情况,可在return处添加如下表达式

( p%2==0 ? 1 : b%k )

即当p为偶数时返回1,否则返回b%k

在return处,调用了cal函数两次,不妨优化一下

long long cal(long long b,long long p,long long k) {
    if(p==1) return b%k;
    int t=cal( b , p/2 , k )%k;
    return ( t * t * ( p%2==0 ? 1 : b%k ))%k;
}

输入输出就不必讲了,放代码

# include <iostream>
# include <cstdio>
//# include <stdio.h>
using namespace std;
long long b,p,k;
long long cal(long long b,long long p,long long k) {
    if(p==1) return b%k;
    int t=cal( b , p>>1 , k )%k;//p>>1 即 p/2
    return ( t * t *( p%2==0 ? 1 : b%k ))%k;
}
int main() {
    cin>>b>>p>>k;
//  scanf("%d%d%d",&b,&p,&k);
    printf("%d^%d mod %d=%d",b,p,k,cal( b , p , k ));
    return 0;
}

  附个洛谷的测试链接P1226 【模板】快速幂||取余运算

标签:b%,return,17,洛谷,long,P1226,cal,取余,mod
来源: https://www.cnblogs.com/skincrab/p/12248006.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有