题目描述:
求 a 乘 b 对 p 取模的值,其中 1 < a,b,p < 10^18 ;
输入描述:
第一行a,第二行b,第三行p
输出描述:
一个整数表示 a乘b mod p的值
样例输入:
3
4
5
样例输出:
2

根据题中的描述,a,b,p的取值都在10^18以内,再进行运算就很容易溢出,所以可以用快速幂的思维来解决
首先需要了解求余的式子
(a×b)%c=(a%c×b%c)%c;
然后开始分析
例100×150mod201;
思路为
a=100,b=150,p=201;
100×150=100×75×2;
//把150分为75×2,然后把那个2乘a,得
a=200,b=75;
a%201=200;
此时为200×75,继续分75,可以换为(74+1)的形式,再对74分为2×37,即
200×(74+1)=200×(2×37+1)=200×2×37+200
a=400%201=199,b=37.//根据求余的式子,可以对a进行操作,使之尽量不溢出。
就按这个思想分下去,一直进行到b不能再分下去,可以看出
当b为偶数时,能被2整除,当b为奇数时,不能直接分出2,需要进行一些操作,所以就先把分出的1×a加到ans上,也就是最后的结果上。就比如上面的200×2×37+200,把+200分出来再对200×2×37进行以后的操作。
while(b)
{
if(b%2==1)
ans=(ans+a)%p;
a=a2%p;
b=b/2;
}
再用位运算的表示
while(b)
{
ans=(ans+a(b&1)%p;
a=a×2%p;
b>>=1;
}
完整代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int a,b,p,ans=0;
cin>>a>>b>>p;
a%=p;
b%=p;
while(b)
{
ans=(ans+a
(b&1))%p;
b>>=1;
a=a*2%p;
}
ans%=p;
cout<<ans;
}