LG8469
题意
已知一个长度为 \(n\) 的序列 \(a\),要构造一个长度为 \(n\) 的序列 \(b\),使得对于 \(1 \le i \le n\),都有 \(b_i \le a_i\),且使 \(\gcd(b_1,b_2,\cdots,b_n)\) 最大,并求出不同的方案数。
分析
既然要使 \(\gcd(b_1,b_2,\cdots,b_n)\) 最大,我们很容易想到令所有的
\(b_i\) 相等,则它们的最大公约数是 \(b_i\)。但由于每个 \(b_i\) 都不能超过
\(a_i\),所以 \(b_i\) 的最大取值就是 \(\min(a_1,a_2,\cdots,a_n)\),即最大公
约数为 \(\min(a_1,a_2,\cdots,a_n)\),第一问解决。
接下来考虑求解方案数。设求出来的最大公约数为 \(k\),那么对于每一个
\(a_i\),很容易得知 \(1\) 到 \(a_i\) 的正整数当中 \(k\) 的倍数有 \(\left \lfloor \dfrac{a_i}{k} \right \rfloor\) 个。因为 \(k\) 的倍数也含有 \(k\) 这个因子,所以第 \(i\) 个数就有 \(\left \lfloor \dfrac{a_i}{k} \right \rfloor\) 种选择。运用乘法原理,得知方案数即为:
\[\left \lfloor \dfrac{a_1}{k} \right \rfloor \times \left \lfloor \dfrac{a_2}{k} \right \rfloor \times \cdots \times \left \lfloor \dfrac{a_n}{k} \right \rfloor
\]
边乘边取模即可。代码实现如下:
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
int main()
{
int n,a[100001],mi=0x7fffffff;
long long ans=1;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
mi=min(mi,a[i]);
}
cout<<mi<<' ';
for(int i=1;i<=n;i++)
ans=ans*(a[i]/mi)%MOD;
cout<<ans;
}
还是菜。