jHN*_*jHN 8 c performance store division modulo
我做了一个(对我来说)非常复杂的任务,我必须在给定n个段时计算最大可能的序列数.
我发现加泰罗尼亚数字表示这个序列,我让它工作n <= 32.我得到的结果应该计算为1.000.000.007.我遇到的问题是"q"和"p"对于一个很长的int而言变得很大而且我在分割"q"和"p"之前不能只修改1.000.000.007因为我会得到不同的结果.
我的问题是,是否有一种非常有效的方法来解决我的问题,还是我必须考虑以不同的方式存储值?我的限制如下: - 仅限stdio.h/iostream - 仅整数 - n <= 20.000.000 - n> = 2
#include <stdio.h>
long long cat(long long l, long long m, long long n);
int main(){
long long n = 0;
long long val;
scanf("%lld", &n);
val = cat(1, 1, n / 2);
printf("%lld", (val));
return 0;
}
long long cat(long long q, long long p, long long n){
if (n == 0) {
return (q / p) % 1000000007;
}
else {
q *= 4 * n - 2;
}
p *= (n + 1);
return cat(q, p, n - 1);
}
Run Code Online (Sandbox Code Playgroud)
为了有效地解决这个问题,您需要使用模算术,并用模逆代替除法。
很容易证明,在没有溢出的情况下,(a * b) % c == ((a % c) * b) % c. 如果我们只是进行乘法,我们可以在每一步对结果取模 1000000007,并且始终保持在 64 位整数的范围内。问题是分裂。(a / b) % c不一定等于((a % c) / b) % c.
为了解决除法问题,我们使用模逆。对于整数a和c以及c素数 和a % c != 0,我们总能找到一个整数b使得a * b % c == 1。这意味着我们可以使用乘法作为除法。对于任何能被,d整除的整数a。(d * b) % c == (d / a) % c这意味着((d % c) * b) % c == (d / a) % c,因此我们可以减少中间结果 mod c 而不会破坏我们的除法能力。
我们要计算的数字的形式为(x1 * x2 * x3 * ...) / (y1 * y2 * y3 * ...) % 1000000007。我们可以改为计算x = x1 % 1000000007 * x2 % 1000000007 * x3 % 1000000007 ...和,然后使用扩展欧几里德算法y = y1 % 1000000007 * y2 % 1000000007 * y3 % 1000000007 ...计算模逆并返回。zy(x * z) % 1000000007
| 归档时间: |
|
| 查看次数: |
193 次 |
| 最近记录: |