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;
}
posted @ 2024-01-20 17:42  liyilang2021  阅读(1)  评论(0编辑  收藏  举报