题目:
沿着河边看一看清冷的夏夜,耳机里是AR的《呼兰河传》。AR的呼兰河并非一条河,而是一个故乡小城的生活日记。静谧的童年,孩子看世界的眼光,花开鸟飞间的自由,塑造了一方那个时代中少有的美好。现在,你需要回答以下问题,才可倾听这首《呼兰河传》带来的温柔,试试吧。给你n个数,选择一些数,使得LCM最大,输出LCM的最大值并对1e9+9取模。
输入描述:
第一行输入一个n,代表数字的个数。
第二行输入n个数a[i],代表每个数的值。
1<=n<=1e6,1<=a[i]<=1e5。
输出描述:
选择一些数能得到的最大LCM,由于LCM太大了,你只需要对1e9+9取模即可。
思路:
显然把所有数字都选的LCM一定是最大的,直接求所有数的LCM即可
直接做LCM的话在取模的时候会出现错误,不能直接求n个数字的LCM
转化为质因数分解,对于每个质因子取最高次幂的结果就是最终的答案
例如 2, 4, 6, 8分别是 2, 2^2, 2∗3, 2^3
最终答案就是 2^3*3
注意一些优化细节,提前做一下素数筛,以及在质因数分解的时候不用跑满所有质因子
然后是数组不必开1e6, 边读边分解就行
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 9;
const int N = 2e5 + 9;
int prime[N], p[N], cnt, mp[N], ans[N];
void Init()
{ //素数筛
int len = sqrt(1e5);
for (int i = 2; i <= len; i++)
{
if (!prime[i])
{
p[++cnt] = i;
mp[i] = cnt;
for (ll j = 2 * i; j <= len; j += i)
prime[j] = 1;
}
}
}
ll quick_pow(ll a, ll b)
{ //快速幂
ll res = 1;
while (b)
{
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
int n;
Init();
cin >> n;
for (int i = 1; i <= n; i++)
{
int pre;
cin >> pre;
for (int j = 1; j <= cnt && pre >= p[j]; j++)
{
int cur = 0;
if (pre % p[j] == 0)
{
while (pre % p[j] == 0)
{
++cur;
pre /= p[j];
}
}
ans[j] = max(ans[j], cur);
}
if (pre > 1)
{
int j = 0;
if (!mp[pre])
{
p[++cnt] = pre;
mp[pre] = cnt;
j = cnt;
}
else
j = mp[pre];
ans[j] = max(1, ans[j]);
}
}
ll res = 1;
for (int i = 1; i <= cnt; i++)
{
res *= quick_pow(p[i], ans[i]);
res %= mod;
}
cout << res << endl;
return 0;
}