64位整数乘法
原题
求 a 乘 b 对 p 取模的值。
输入格式
第一行输入整数a,第二行输入整数b,第三行输入整数p。
输出格式
输出一个整数,表示a*b mod p
的值。
数据范围
\(1≤a,b,p≤10^{18}\)
输入样例:
3
4
5
输出样例:
2
- 这题可以用大数相乘,但是没必要那么麻烦,可以用这个位运算的思想把b个a相加起来
#include<iostream>
using namespace std;
int main(void)
{
long long a,b,p,res=0;
cin>>a>>b>>p;
while(b)
{
if(b & 1)
res=(res + a) % p;
a=a*2%p;
b >>= 1;
}
cout<<res<<endl;
return 0;
}
- 另外一种方法:\(a \times b \ mod \ p = a \times b - \lfloor a \times b \div p \rfloor \times p\)
- 当\(a , b < p\)时,\(a \times b \div p\)下取整之后也一定小于p.浮点类型
long double
在十进制下有效数字有\(18 \sim 19\)位,足够胜任.当浮点数的精度不足以保存精确数值时,会像科学记数法一样舍弃低位. - \(a\times b\)和\(\lfloor a \times b \div p \rfloor \times p\) 可能很大,但是二者的差一定在\(0 \sim p-1\)之间。
- 当\(a , b < p\)时,\(a \times b \div p\)下取整之后也一定小于p.浮点类型
#include<iostream>
using namespace std;
int main()
{
long long a,b,p,res = 0;
cin>> a >> b >> p;
a %= p,b %= p;
long long c = (long double) a * b / p;
long long ans = a * b - c * p;
if(ans < 0)
ans += p;
else if(ans >= p)
ans -= p;
cout<< ans <<endl;
return 0;
}