64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二

Posted Tisfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二相关的知识,希望对你有一定的参考价值。

64位整数乘法

题目描述

a ∗ b a*b ab m o d mod mod取模的值

1 ≤ a , b , m o d ≤ 1 0 18 1\\leq a,b,mod\\leq 10^{18} 1a,b,mod1018

问题分析

先不考虑 _ _ 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 ab%mod=abab/modmod(其中 ⌊ ⌋ \\lfloor \\rfloor 表示向下取整)

a ∗ b a*b ab x x x ⌊ a ∗ b / m o d ⌋ \\lfloor a*b/mod\\rfloor ab/mod y y y

问题有 2 2 2个,一是如何计算出 ⌊ a ∗ b / m o d ⌋ \\lfloor a*b/mod\\rfloor ab/mod,而是如何计算 x − y ∗ m o d x-y*mod xymod

因为 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 abcmod其实就是 a ∗ b % m o d ≤ m o d < 2 64 a*b\\%mod\\leq mod< 2^{64} ab%modmod<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} abcmod=(abcmod)%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 xymod由此计算。

时间复杂度为 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 ab m o d mod mod取模的值

Tips

1 ≤ a , b , m o d ≤ 1 0 18 1\\leq a,b,mod\\leq 10^{18} 1a,b,mod1018


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位整数乘法-《算法竞赛进阶指南》

64位整数乘法讲解-And-AcWing-90. 64位整数乘法-方法二-《算法竞赛进阶指南》

[位运算] 64位整数乘法(mod 一个数)

ACwing90 64位整数乘法 大数乘法取模

64位整数乘法

90. 64位整数乘法位运算