找到可从1到N的所有数字整除的最小数字,不留任何余数。由于数字可能非常大,我们采用模数1000000007的答案。
我认为可以被1到N的所有数字整除的最小数字是LCM(1..N)。
示例:对于N = 5,最小的数字为60。
因为60是可以被所有数字形式整除的最小数字(1-5)。
但是由于一些奇怪的原因,它给了我大的N(1000)等的错误答案。 什么可能导致可能的错误,我的登录在这里是正确的吗?
这是我试图实施的内容。
#include <iostream>
#include <vector>
using namespace std;
vector<long long> lcmArr;
const long long mod = 1000000007;
long long gcd(long long a, long long b){
if(b == 0)
{
return a;
}
return gcd(b, a%b);
}
long long lcmFumction(long long a, long long b)
{
return (a*b)/gcd(a,b);
}
int main() {
lcmArr.clear();lcmArr.resize(1002);
lcmArr[0] =0; lcmArr[1] = 1;
for(int i =2; i <=1000; i++){
lcmArr[i] = lcmFumction(lcmArr[i-1], i)%mod;
//cout<<lcmArr[i-1]<<" ";
}
int T;
cin >> T;
while(T--) {
int N;
cin>>N;
cout<<lcmArr[N]<<"\n";
}
return 0;
}
答案 0 :(得分:6)
问题是当你计算LCM时,你使用除法,
并且
((A/B)/C) mod M != (((A/B) mod M)/C)mod M
例如(10/5/2) % 2 != ((10/5)%2)/2)%2
您应该使用modular inverse来计算。
关于模逆的一些解释。
如果我们有:
(a*b) % m = 1
,然后b
与a
呈模块化反转,为b % m = (1/a) % m
。
因此,如果我们需要计算(x/a) % m
,我们可以将其变为(x * b ) %m
。
我们知道(A*B*C)% m = ((A * B) % m)*C)% m
,因此,在您的情况下,模块化逆会派上用场。
答案 1 :(得分:1)
我知道上面的答案已被接受,但我认为这还不足以解决您的问题。问题在于第一个模块化LCM将带走您在后续GCD呼叫中检查所需的所有除数,因此答案仍然是错误的。
一种可能的解决方案是为答案保留一系列因素。每个因子将是1..N中的每个数字,除以GCD(数字,[所有以前的数字])。为此,您必须编写一个特殊的GCD代码,用于计算单个数字和一系列因子之间的结果。这个C ++代码显示了它的工作原理:
#include <iostream>
#include <vector>
#define lli long long int
using namespace std;
vector<lli> T;
lli gcd(lli a, lli b) {
if(b == 0)
return a;
return gcd(b, a%b);
}
lli gcd_vector(vector<lli>& a, lli b) {
lli ma = 1;
for(int i=0; i<T.size(); i++)
ma = ma*T[i]%b;
return gcd(b, ma);
}
int main() {
lli answer = 1;
for(int i=1; i<=1000; i++) {
lli factor = i/gcd_vector(T, i);
T.push_back(factor);
answer = (answer*factor)%1000000007;
}
cout << answer << endl;
}