在大模下乘大整数

给定一个整数a,b,m。求(a*b)mod m,其中a,b可能很大,它们的直接乘法可能会导致溢出。但是,它们小于允许的最大long int值的一半。

null

例如:

Input: a = 426, b = 964, m = 235Output: 119Explanation: (426 * 964) % 235              = 410664 % 235            = 119Input: a = 10123465234878998,        b = 65746311545646431       m = 10005412336548794 Output: 4652135769797794

A. 缺乏经验的 方法是使用任意精度的数据类型,例如 智力 用python或 大整数 用Java编写的类。但这种方法不会有什么成效,因为字符串到int的内部转换,然后执行操作,会导致二进制系统中加法和乘法的计算速度减慢。

高效的解决方案: 因为a和b可能是非常大的数字,如果我们试图直接相乘,那么它肯定会溢出。因此,我们使用乘法的基本方法。, a*b=a+a+…+a(b次) 所以我们可以很容易地计算加法的值(在模m下),而不需要任何计算 计算溢出。但如果我们试图增加 A. 反复达到 B 那么,对于b的大值,它肯定会超时,因为这种方法的时间复杂度将变成O(b)。

因此,我们将上述重复的步骤 A. 以更简单的方式,即:。,

If b is even then   a * b = 2 * a * (b / 2), otherwise   a * b = a + a * (b - 1)

以下是描述上述解释的方法:

C++

// C++ program of finding modulo multiplication
#include<bits/stdc++.h>
using namespace std;
// Returns (a * b) % mod
long long moduloMultiplication( long long a,
long long b,
long long mod)
{
long long res = 0; // Initialize result
// Update a if it is more than
// or equal to mod
a %= mod;
while (b)
{
// If b is odd, add a with result
if (b & 1)
res = (res + a) % mod;
// Here we assume that doing 2*a
// doesn't cause overflow
a = (2 * a) % mod;
b >>= 1; // b = b / 2
}
return res;
}
// Driver program
int main()
{
long long a = 426;
long long b = 964;
long long m = 235;
cout << moduloMultiplication(a, b, m);
return 0;
}
// This code is contributed
// by Akanksha Rai


C

// C program of finding modulo multiplication
#include<stdio.h>
// Returns (a * b) % mod
long long moduloMultiplication( long long a,
long long b,
long long mod)
{
long long res = 0; // Initialize result
// Update a if it is more than
// or equal to mod
a %= mod;
while (b)
{
// If b is odd, add a with result
if (b & 1)
res = (res + a) % mod;
// Here we assume that doing 2*a
// doesn't cause overflow
a = (2 * a) % mod;
b >>= 1; // b = b / 2
}
return res;
}
// Driver program
int main()
{
long long a = 10123465234878998;
long long b = 65746311545646431;
long long m = 10005412336548794;
printf ( "%lld" , moduloMultiplication(a, b, m));
return 0;
}


JAVA

// Java program of finding modulo multiplication
class GFG
{
// Returns (a * b) % mod
static long moduloMultiplication( long a,
long b, long mod)
{
// Initialize result
long res = 0 ;
// Update a if it is more than
// or equal to mod
a %= mod;
while (b > 0 )
{
// If b is odd, add a with result
if ((b & 1 ) > 0 )
{
res = (res + a) % mod;
}
// Here we assume that doing 2*a
// doesn't cause overflow
a = ( 2 * a) % mod;
b >>= 1 ; // b = b / 2
}
return res;
}
// Driver code
public static void main(String[] args)
{
long a = 10123465234878998L;
long b = 65746311545646431L;
long m = 10005412336548794L;
System.out.print(moduloMultiplication(a, b, m));
}
}
// This code is contributed by Rajput-JI


Python3

# Python 3 program of finding
# modulo multiplication
# Returns (a * b) % mod
def moduloMultiplication(a, b, mod):
res = 0 ; # Initialize result
# Update a if it is more than
# or equal to mod
a = a % mod;
while (b):
# If b is odd, add a with result
if (b & 1 ):
res = (res + a) % mod;
# Here we assume that doing 2*a
# doesn't cause overflow
a = ( 2 * a) % mod;
b >> = 1 ; # b = b / 2
return res;
# Driver Code
a = 10123465234878998 ;
b = 65746311545646431 ;
m = 10005412336548794 ;
print (moduloMultiplication(a, b, m));
# This code is contributed
# by Shivi_Aggarwal


C#

// C# program of finding modulo multiplication
using System;
class GFG
{
// Returns (a * b) % mod
static long moduloMultiplication( long a,
long b,
long mod)
{
long res = 0; // Initialize result
// Update a if it is more than
// or equal to mod
a %= mod;
while (b > 0)
{
// If b is odd, add a with result
if ((b & 1) > 0)
res = (res + a) % mod;
// Here we assume that doing 2*a
// doesn't cause overflow
a = (2 * a) % mod;
b >>= 1; // b = b / 2
}
return res;
}
// Driver code
static void Main()
{
long a = 10123465234878998;
long b = 65746311545646431;
long m = 10005412336548794;
Console.WriteLine(moduloMultiplication(a, b, m));
}
}
// This code is contributed
// by chandan_jnu


PHP

<?php
//PHP program of finding
// modulo multiplication
// Returns (a * b) % mod
function moduloMultiplication( $a , $b , $mod )
{
$res = 0; // Initialize result
// Update a if it is more than
// or equal to mod
$a %= $mod ;
while ( $b )
{
// If b is odd,
// add a with result
if ( $b & 1)
$res = ( $res + $a ) % $mod ;
// Here we assume that doing 2*a
// doesn't cause overflow
$a = (2 * $a ) % $mod ;
$b >>= 1; // b = b / 2
}
return $res ;
}
// Driver Code
$a = 10123465234878998;
$b = 65746311545646431;
$m = 10005412336548794;
echo moduloMultiplication( $a , $b , $m );
// This oce is contributed by ajit
?>


Javascript

<script>
// JavaScript program for the above approach
// Returns (a * b) % mod
function moduloMultiplication(a, b, mod)
{
// Initialize result
let res = 0;
// Update a if it is more than
// or equal to mod
a = (a % mod);
while (b > 0)
{
// If b is odd, add a with result
if ((b & 1) > 0)
{
res = (res + a) % mod;
}
// Here we assume that doing 2*a
// doesn't cause overflow
a = (2 * a) % mod;
b = (b >> 1); // b = b / 2
}
return res;
}
// Driver Code
let a = 426;
let b = 964;
let m = 235;
document.write(moduloMultiplication(a, b, m));
// This code is contributed by code_hunt
</script>


输出

4652135769797794

时间复杂性: O(日志b) 辅助空间: O(1)

注: 只有在以下情况下,上述方法才会起作用: 2*m 可以用标准数据类型表示,否则会导致溢出。

本文由 Shubham Bansal .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享