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\)之间。
#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;
}
posted @ 2020-08-01 23:56  zko  阅读(187)  评论(0编辑  收藏  举报