[英]modulo formula in C++
I Have this formula: (n - 1)!我有这个公式:(n - 1)! ((n (n - 1))/2 + ((n - 1) (n - 2))/4)
2<=n<=100000
I would like to modulate the result of this from this formula by any modulo, but for the moment let's assume that it is constant, MOD = 999999997
. ((n (n - 1))/2 + ((n - 1) (n - 2))/4)
2<=n<=100000
我想通过任何模来调制这个公式的结果,但目前让我们假设它是恒定的, MOD = 999999997
。 Unfortunately I can't just calculate the result and modulate it, because unfortunately I don't have variables larger than 2^64
at my disposal, so the main question is.不幸的是,我不能只计算结果并对其进行调制,因为不幸的是我没有大于
2^64
的变量可供我使用,所以主要问题是。 What factors to modulate by MOD to get the results%MOD? MOD 调制哪些因素才能得到结果%MOD? Now let's assume that
n=19
.现在让我们假设
n=19
。 What is in brackets is equal to 247.5
括号内等于
247.5
18! = 6402373705728000
18! = 6402373705728000
. 18! = 6402373705728000
。 (6402373705728000 * 247.5)mod999999997 = 921442488
. (6402373705728000 * 247.5)mod999999997 = 921442488
。 Unfortunately, in case I modulate 18, first, the result will be wrong, because (18.)mod999999997 = 724935119. (724935119 * 247.5)mod9999997 = 421442490.
How to solve this problem?不幸的是,如果我调制 18,首先,结果会出错,因为
(18.)mod999999997 = 724935119. (724935119 * 247.5)mod9999997 = 421442490.
如何解决这个问题?
I think the sum could be break down.我认为总和可以分解。 The only tricky part here is that
(n - 1)(n - 2)/4
may have a .5
decimal., as n(n-1) / 2
will always be integer.这里唯一棘手的部分是
(n - 1)(n - 2)/4
可能有.5
小数。因为n(n-1) / 2
将始终是 integer。
S = (n - 1)! * ((n (n - 1))/2 + ((n - 1) (n - 2))/4)
= [(n-1)! * (n*(n-1)/2)] + [(n-1)! * (n-1)(n-2)/4]
= A + B
A
is easy to do. A
很容易做到。 With B
, if (n-1)(n-2) % 4 == 0
then there's nothing else either, else you can simplified to X/2
, as (n-1)(n-2)
is also divisible by 2.使用
B
,如果(n-1)(n-2) % 4 == 0
则没有别的,否则您可以简化为X/2
,因为(n-1)(n-2)
也可被 2 整除.
If n = 2
, it's trivial, else if n > 2
there's always a 2 in the representation of (N-1). = 1x2x3x... xN
如果
n = 2
,它是微不足道的,否则如果n > 2
在(N-1). = 1x2x3x... xN
(N-1). = 1x2x3x... xN
. (N-1). = 1x2x3x... xN
。 In that case, simply calculate ((N-1)./2) = 1x3x4x5x... xN
.在这种情况下,只需计算
((N-1)./2) = 1x3x4x5x... xN
。
Late example:后期示例:
N = 19
MOD = 999999997
--> 18! % MOD = 724935119 (1)
(18!/2) % MOD = 862467558 (2)
n(n-1)/2 = 171 (3)
(n-1)(n-2)/2 = 153 (4)
--> S = (1)*(3) + (2)*(4) = 255921441723
S % MOD = 921442488
On another note, if mod
is some prime number, like 1e9+7
, you can just apply Fermat's little theorem to calculate multiplicative inverse as such:另一方面,如果
mod
是一些素数,例如1e9+7
,您可以应用费马小定理来计算乘法逆:
(a/b) % P = [(a%P) * ((b^(P-2)) % P)] % P (with P as prime, a and b are co-prime to P)
You will have to use 3 mathematical formulas here:您将不得不在这里使用 3 个数学公式:
(a + b) mod c == (a mod c + b mod c) mod c
and和
(a * b) mod c == (a mod c * b mod c) mod c
But those are only valid for integers.但这些仅对整数有效。 The nice part here is that formula can only be integer for n >= 2, provided you compute it as:
这里好的部分是公式只能是 integer 对于 n >= 2,前提是您将其计算为:
(((n - 1)! * n * (n - 1))/2) + (((n - 1)! * (n - 1) * (n - 2))/4)
1st part is integer | 2nd part is too
for n == 2, first part boils down to 1 and second is 0对于 n == 2,第一部分归结为 1,第二部分为 0
for n > 2 either n or n-1 is even so first part is integer, and again eithe n-1 of n-2 is even and (n-1).对于 n > 2,n 或 n-1 是偶数,所以第一部分是 integer,并且 n-2 的 n-1 也是偶数和 (n-1)。 is also even so second part is integer.
甚至第二部分也是整数。 As your formula can be rewritten to only use additions and multiplications it can be computed
由于您的公式可以重写为仅使用加法和乘法,因此可以计算
First of All, for n=2 we can say that the result is 1. Then, the expression is equal to: (n*(n-1) (n-1)!)/2 + (((n-1) (n-2)/2)^2)*(n-3).首先,对于 n=2,我们可以说结果是 1。然后,表达式等于: (n*(n-1) (n-1)!)/2 + (((n-1) (n-2)/2)^2)*(n-3)。 .
.
lemma: For every two consecutive integer number, one of them is even.引理:对于每两个连续的 integer 数,其中一个是偶数。
By lemma we can understand that n*(n-1) is even and also (n-1)*(n-2) is even too.通过引理,我们可以理解 n*(n-1) 是偶数, (n-1)*(n-2) 也是偶数。 So we know that the answer is an integer number.
所以我们知道答案是一个 integer 号码。
First we calculate (n*(n-1) (n-1).)/2 modulo MOD.首先我们计算 (n*(n-1) (n-1).)/2 模 MOD。 We can calculate (n (n-1))/2 that can be saved in a long long variable like x, and we get the mod of it modulo MOD:
我们可以计算 (n (n-1))/2 可以保存在像 x 这样的 long long 变量中,我们得到它的 mod 模 MOD:
x = (n*(n-1))/2;
x %= MOD;
After that for: i (n-1 -> 1) we do:之后对于: i (n-1 -> 1) 我们这样做:
x = (x*i)%MOD;
And we know that both of 'x' and 'i' are less than MOD and the result of multiplication can be save in a long long variable.我们知道 'x' 和 'i' 都小于 MOD 并且乘法的结果可以保存在一个 long long 变量中。
And likewise we do the same for (((n-1) (n-2)/2)^2) (n-3).同样,我们对 (((n-1) (n-2)/2)^2) (n-3) 做同样的事情。 , We calculate (n-1)*(n-2)/2 that can be save in a long long variable like y: and we get the mod of it modulo MOD:
, 我们计算 (n-1)*(n-2)/2 可以保存在像 y 的 long long 变量中:我们得到它的 mod 模 MOD:
y = ((n-1)*(n-2))/2;
y %= MOD;
And after that we replace (y^2)%MOD on y because we know that y is less than MOD and y*y can be save in a long long variable:之后我们在 y 上替换 (y^2)%MOD 因为我们知道 y 小于 MOD 并且 y*y 可以保存在一个 long long 变量中:
y = (y*y)%MOD;
Then like before for: i (n-3 -> 1) we do:然后像以前一样 for: i (n-3 -> 1) 我们这样做:
y = (y*i)%MOD;
And finally the answer is (x+y)%MOD最后的答案是 (x+y)%MOD
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.