64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二-《算法竞赛进阶指南》
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二-《算法竞赛进阶指南》相关的知识,希望对你有一定的参考价值。
64位整数乘法
题目描述
求 a ∗ b a*b a∗b对 m o d mod mod取模的值
1 ≤ a , b , m o d ≤ 1 0 18 1\\leq a,b,mod\\leq 10^{18} 1≤a,b,mod≤1018
问题分析
先不考虑 _ _ i n t 128 \\_\\_int128 __int128
利用 a ∗ b % m o d = a ∗ b − ⌊ a ∗ b / m o d ⌋ ∗ m o d a*b\\%mod=a*b-\\lfloor a*b/mod\\rfloor*mod a∗b%mod=a∗b−⌊a∗b/mod⌋∗mod(其中 ⌊ ⌋ \\lfloor \\rfloor ⌊⌋表示向下取整)
记 a ∗ b a*b a∗b为 x x x, ⌊ a ∗ b / m o d ⌋ \\lfloor a*b/mod\\rfloor ⌊a∗b/mod⌋为 y y y
问题有 2 2 2个,一是如何计算出 ⌊ a ∗ b / m o d ⌋ \\lfloor a*b/mod\\rfloor ⌊a∗b/mod⌋,而是如何计算 x − y ∗ m o d x-y*mod x−y∗mod
因为 l o n g d o u b l e long\\ double long double在十进制下的有效数字有 18 18 18~ 19 19 19位,当 a , b < m o d a,b<mod a,b<mod时 c c c也一定小于 m o d mod mod。所以 l o n g d o u b l e long\\ double long double可以胜任,再把结果强制转换为 u n s i g n e d l o n g l o n g unsigned\\ long\\ long unsigned long long即可。 y y y由此计算。
因为 a ∗ b − c ∗ m o d a*b-c*mod a∗b−c∗mod其实就是 a ∗ b % m o d ≤ m o d < 2 64 a*b\\%mod\\leq mod< 2^{64} a∗b%mod≤mod<264,所以 a ∗ b − c ∗ m o d = ( a ∗ b − c ∗ m o d ) % 2 64 a*b-c*mod=(a*b-c*mod)\\%2^{64} a∗b−c∗mod=(a∗b−c∗mod)%264,又因为 u n s i g n e d l o n g l o n g unsigned\\ long\\ long unsigned long long溢出时相当于对 2 64 2^{64} 264自动取模,所以 x − y ∗ m o d x-y*mod x−y∗mod由此计算。
时间复杂度为 O ( 1 ) O(1) O(1)
64位整数乘法模板
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a, ll b, ll mod)
{
a %= mod, b %= mod;
ull c = (long double)a * b / mod;
ull x = a * b, y = c * mod;
ll ans = (ll)x % mod - (ll)y % mod;
if (ans < 0)
ans += mod;
return ans;
}
AcWing-90. 64位整数乘法
Problem Description
求 a ∗ b a*b a∗b对 m o d mod mod取模的值
Tips
1 ≤ a , b , m o d ≤ 1 0 18 1\\leq a,b,mod\\leq 10^{18} 1≤a,b,mod≤1018
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a, ll b, ll mod)
{
a %= mod, b %= mod;
ull c = (long double)a * b / mod;
ull x = a * b, y = c * mod;
ll ans = (ll)x % mod - (ll)y % mod;
if (ans < 0)
ans += mod;
return ans;
}
int main()
{
ll a, b, c;
cin >> a >> b >> c;
cout << mul(a, b, c) << endl;
return 0;
}
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/119149367
以上是关于64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二-《算法竞赛进阶指南》的主要内容,如果未能解决你的问题,请参考以下文章
64位整数乘法讲解-And-AcWing-90. 64位整数乘法-《算法竞赛进阶指南》