Modulo product when the divisor is greater than both large factors - c++

In my C++ code I have three uint64_tvariables:
uint64_t a = 7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;
I need to find (a * b) % c. If I directly multiply a and b, it will cause overflow. However, I can't apply the formula (a * b) % c = ((a % c) * (b % c)) % c, because c > a, c > b and, consequently, a % c = a, a % c = b and I will end up multiplying a and b again, which again will result in overflow.
How can I compute (a * b) % c for these values (and such cases in general) of the variables without overflow?

A simple solution is to define x = 2^32 = 4.29... 10^9
and then to represent a and b as:
a = ka * x + a1 with ka, a1 < x
b = kb * x + b1 with kb, b1 < x
Then
a*b = (ka * x + a1) * (kb * x + b1) = ((ka * kb) * x) * x
+ x * (b1 * ka) + x * (a1 * kb) + a1 * b1
All these operations can be performed without the need of a larger type, assuming that all the operations are performed in Z/cZ, i.e. assuming that % c operation is performed after each operation (* or +)

There are more elegant solutions than this, but an easy one would be looking into a library that deals with larger numbers. It will handle numbers that are too large for the largest of normal types for you. Check this one out: https://gmplib.org/

Create a class or struct to deal with numbers in parts.
Example PsuedoCode
// operation enum to know how to construct a large number
enum operation {
case add;
case sub;
case mult;
case divide;
}
class bigNumber {
//the two parts of the number
int partA;
int partB;
bigNumber(int numA, int numB, operation op) {
if(op == operation.mult) {
// place each digit of numA into an integer array
// palce each digit of numB into an integer array
// Iteratively place the first half of digits into the partA member
// Iteratively place the second half of digits into the partB member
} else if //cases for construction from other operations
}
// Create operator functions so you can perform arithmetic with this class
}
uint64_t a = 7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;
bigNumber bigNum = bigNumber(a, b, .mult);
uint64_t result = bigNum % c;
print(result);
Keep in mind that you may want to make result of type bigNumber if the value of c is very small. Basically this was just sort of an outline, make sure if you use a type that it won't overflow.

Related

Calculate large multiplication and divide under modulus

In C++, I have a problem need to calculate ((a * b * c) / n) % m with large a, b and c (0 < a, b, c <= 10^9 and n, m > 0). And the problem guaranteed that a * b * c is divisible by n.
I tried calc ((a * b) % m * c) % m) / n but it's not a right answer.
Idea is to keep removing the common factors in numerator and denominator by calculating gcd and dividing it out. It is illustrated in following python code. In C++, gcd can be easily calculated using extended euclid's algorithm.
import math
def prod(a,b,c,n):
num = [a,b,c]
p = 1
tmp = n
for i in range(len(num)):
g = math.gcd(num[i],tmp)
num[i] /= g
tmp /= g
p = (p*num[i]) % n
return p

Code to find X such that the product (A ^ X) * (B ^ X) is maximised

Find X such that (A ^ X) * (B ^ X) is maximum
Given A, B, and N (X < 2^N)
Return the maximum product modulus 10^9+7.
Example:
A = 4
B = 6
N = 3
We can choose X = 3 and (A ^ X) = 7 and (B ^ X) = 5.
The product will be 35 which is the maximum.
Here is my code:
int limit = (1<<n) - 1;
int MOD = 1_000_000_007;
int maxProd = 1;
for(int i = 1; i <= limit; i++){
int x1 = (A^i);
int x2 = (B^i);
maxProd = max(maxProd, (x1*x2) % MOD);
}
return maxProd;
for bits >=Nth bit, X will be zero, A^X and B^X are A and B for those bits
find set bits and zero bits shared by A and B from 0 to N-1th bits. for set bits, X will be zero there. for zero bits, X will be 1 there.
for bits that A and B are different, X will be either 0 or 1
from 1,2, we will have the value for A and B, denoted by a and b. a and b are known constants
from 3, we will have a bunch of 2^k, such as 2^3, 2^1,…, say the tot sum of them is tot. tot is a known constant
the question becomes max (a+tot-sth)*(b+sth), where sth is the subset sum of some 2^k from 3, while a,tot,and b are constants
when (a+tot-sth) and (b+sth) are as close as possible, the product will be maxed.
if a==b, we will give the most significant bit of step 3 to either a or b, and the rest to the other one
if a!=b, we will give all bits in step 3 to the smaller one

modular exponentiation for summation series

I am working on a project for school and I have run into a problem. Our goal is to calculate the last six decimal digits of the series of sums, n, i = 0, i^i using modular arithmetic. I have found a recursive method online to help me better understand how modular exponentiation works.
int exponentMod(int A, int B, int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long y;
if (B % 2 == 0) {
y = exponentMod(A, B / 2, C);
y = (y * y) % C;
}
// If B is odd
else {
y = A % C;
y = (y * exponentMod(A, B - 1, C) % C) % C;
}
return (int)((y + C) % C);
}
This method works fine when I am just calculating one exponent, however I'm not sure how to make this work for the problem I have been given with the series. The purpose of modular exponentiation is because we are working with large exponents, so I can not just add them up normally then mod by 1000000. I can't add up the numbers output by the above function either because they don't produce the full number that I need, when the numbers get larger, to get the correct summation. Can Someone point me in the right direction for finding the last six digits of the summation using modular arithmetic?

How can you calculate a factor if you have the other factor and the product with overflows?

a * x = b
I have a seemingly rather complicated multiplication / imul problem: if I have a and I have b, how can I calculate x if they're all 32-bit dwords (e.g. 0-1 = FFFFFFFF, FFFFFFFF+1 = 0)?
For example:
0xcb9102df * x = 0x4d243a5d
In that case, x is 0x1908c643. I found a similar question but the premises were different and I'm hoping there's a simpler solution than those given.
Numbers have a modular multiplicative inverse modulo a power of two precisely iff they are odd. Everything else is a bit-shifted odd number (even zero, which might be anything, with all bits shifted out). So there are a couple of cases:
Given a * x = b
tzcnt(a) > tzcnt(b) no solution
tzcnt(a) <= tzcnt(b) solvable, with 2tzcnt(a) solutions
The second case has a special case with 1 solution, for odd a, namely x = inverse(a) * b
More generally, x = inverse(a >> tzcnt(a)) * (b >> tzcnt(a)) is a solution, because you write a as (a >> tzcnt(a)) * (1 << tzcnt(a)), so we cancel the left factor with its inverse, we leave the right factor as part of the result (cannot be cancelled anyway) and then multiply by what remains to get it up to b. Still only works in the second case, obviously. If you wanted, you could enumerate all solutions by filling in all possibilities for the top tzcnt(a) bits.
The only thing that remains is getting the inverse, you've probably seen it in the other answer, whatever it was, but for completeness you can compute it as follows: (not tested)
; input x
dword y = (x * x) + x - 1;
dword t = y * x;
y *= 2 - t;
t = y * x;
y *= 2 - t;
t = y * x;
y *= 2 - t;
; result y

How to calculate (n!)%1000000009

I need to find n!%1000000009.
n is of type 2^k for k in range 1 to 20.
The function I'm using is:
#define llu unsigned long long
#define MOD 1000000009
llu mulmod(llu a,llu b) // This function calculates (a*b)%MOD caring about overflows
{
llu x=0,y=a%MOD;
while(b > 0)
{
if(b%2 == 1)
{
x = (x+y)%MOD;
}
y = (y*2)%MOD;
b /= 2;
}
return (x%MOD);
}
llu fun(int n) // This function returns answer to my query ie. n!%MOD
{
llu ans=1;
for(int j=1; j<=n; j++)
{
ans=mulmod(ans,j);
}
return ans;
}
My demand is such that I need to call the function 'fun', n/2 times. My code runs too slow for values of k around 15. Is there a way to go faster?
EDIT:
In actual I'm calculating 2*[(i-1)C(2^(k-1)-1)]*[((2^(k-1))!)^2] for all i in range 2^(k-1) to 2^k. My program demands (nCr)%MOD caring about overflows.
EDIT: I need an efficient way to find nCr%MOD for large n.
The mulmod routine can be speeded up by a large factor K.
1) '%' is overkill, since (a + b) are both less than N.
- It's enough to evaluate c = a+b; if (c>=N) c-=N;
2) Multiple bits can be processed at once; see optimization to "Russian peasant's algorithm"
3) a * b is actually small enough to fit 64-bit unsigned long long without overflow
Since the actual problem is about nCr mod M, the high level optimization requires using the recurrence
(n+1)Cr mod M = (n+1)nCr / (n+1-r) mod M.
Because the left side of the formula ((nCr) mod M)*(n+1) is not divisible by (n+1-r), the division needs to be implemented as multiplication with the modular inverse: (n+r-1)^(-1). The modular inverse b^(-1) is b^(M-1), for M being prime. (Otherwise it's b^(phi(M)), where phi is Euler's Totient function.)
The modular exponentiation is most commonly implemented with repeated squaring, which requires in this case ~45 modular multiplications per divisor.
If you can use the recurrence
nC(r+1) mod M = nCr * (n-r) / (r+1) mod M
It's only necessary to calculate (r+1)^(M-1) mod M once.
Since you are looking for nCr for multiple sequential values of n you can make use of the following:
(n+1)Cr = (n+1)! / ((r!)*(n+1-r)!)
(n+1)Cr = n!*(n+1) / ((r!)*(n-r)!*(n+1-r))
(n+1)Cr = n! / ((r!)*(n-r)!) * (n+1)/(n+1-r)
(n+1)Cr = nCr * (n+1)/(n+1-r)
This saves you from explicitly calling the factorial function for each i.
Furthermore, to save that first call to nCr you can use:
nC(n-1) = n //where n in your case is 2^(k-1).
EDIT:
As Aki Suihkonen pointed out, (a/b) % m != a%m / b%m. So the method above so the method above won't work right out of the box. There are two different solutions to this:
1000000009 is prime, this means that a/b % m == a*c % m where c is the inverse of b modulo m. You can find an explanation of how to calculate it here and follow the link to the Extended Euclidean Algorithm for more on how to calculate it.
The other option which might be easier is to recognize that since nCr * (n+1)/(n+1-r) must give an integer, it must be possible to write n+1-r == a*b where a | nCr and b | n+1 (the | here means divides, you can rewrite that as nCr % a == 0 if you like). Without loss of generality, let a = gcd(n+1-r,nCr) and then let b = (n+1-r) / a. This gives (n+1)Cr == (nCr / a) * ((n+1) / b) % MOD. Now your divisions are guaranteed to be exact, so you just calculate them and then proceed with the multiplication as before. EDIT As per the comments, I don't believe this method will work.
Another thing I might try is in your llu mulmod(llu a,llu b)
llu mulmod(llu a,llu b)
{
llu q = a * b;
if(q < a || q < b) // Overflow!
{
llu x=0,y=a%MOD;
while(b > 0)
{
if(b%2 == 1)
{
x = (x+y)%MOD;
}
y = (y*2)%MOD;
b /= 2;
}
return (x%MOD);
}
else
{
return q % MOD;
}
}
That could also save some precious time.