牛客网 64位整数乘法

题目描述

求 a 乘 b 对 p 取模的值,其中 1≤a,b,p≤1018
输入描述:
第一行a,第二行b,第三行p。
输出描述:
一个整数,表示a×b mod p的值。
示例1
输入
2
3
9
输出
6
题目链接:https://ac.nowcoder.com/acm/contest/996/C
来源:牛客网

解析

很显然,直接返回a*b%p势必会出现乘法溢出的情况!借鉴快速幂的思想,可以得到如下解决方案:
1.将a*b改为b个a相加,不断对a做"a=a+a"的迭代,可依据b选择对应的迭代值a加入到累加值res中,使得res恰好为初始a值的b倍。
2.由于模运算存在这样一个性质:(a+b)%p=(a%p+b%p)%p。同样可以推广到(a+b+c+…)%p=(a%p+b%p+c%p+…)%p。用文字表述就是任意多个加数相加后再取模等于各加数取模后相加再取模。故只需要每一步都对加数(a+a)取模,每一步都对“各加数取模后相加”得到的(res+a)取模。如此就防止了乘法的溢出,同时快速幂的思想也保证了较低的时间复杂度。
附上之前写的快速幂详解!(通俗易懂),以做对比学习。

AC代码

#include<iostream>
using namespace std;
typedef long long LL;
 LL multi(LL a,LL b,LL p){    
 LL res=0;
 while(b>0){
 if(b&1) res=(res+a)%p;  / /对“各加数取模后相加”得到的(res+a)取模
 a=(a+a)%p;             / /对加数(a+a)取模
 b=b>>1;
 }    
 return res;    
 }
int main(){     
LL a,b,p; 
cin>>a>>b>>p;   
cout<<multi(a,b,p);    
  return 0;  
}

上一篇博客:快速幂详解(通俗易懂!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值