题目链接
求n个数的LCM。
由唯一分解定理得:
a = p 1 k 1 × p 2 k 2 × p 3 k 3 × . . . × p m k m a=p_1^{k_1}\times p_2^{k_2}\times p_3^{k_3}\times ...\times p_m^{k_m} a=p1k1×p2k2×p3k3×...×pmkm
b = p 1 j 1 × p 2 j 2 × p 3 j 3 × . . . × p m j m b=p_1^{j_1}\times p_2^{j_2}\times p_3^{j_3}\times ...\times p_m^{j_m} b=p1j1×p2j2×p3j3×...×pmjm
其中p为质数。
有
g c d ( a , b ) = p 1 m i n ( k 1 , j 1 ) × p 2 m i n ( k 2 , j 2 ) × p 3 m i n ( k 3 , j 3 ) × . . . × p m m i n ( k m , j m ) gcd(a,b)=p_1^{min(k_1,j_1)}\times p_2^{min(k_2,j_2)}\times p_3^{min(k_3,j_3)}\times ...\times p_m^{min(k_m,j_m)} gcd(a,b)=p1min(k1,j1)×p2min(k2,j2)×p3min(k3,j3)×...×pmmin(km,jm)
l c m ( a , b ) = p 1 m a x ( k 1 , j 1 ) × p 2 m a x ( k 2 , j 2 ) × p 3 m a x ( k 3 , j 3 ) × . . . × p m m a x ( k m , j m ) lcm(a,b)=p_1^{max(k_1,j_1)}\times p_2^{max(k_2,j_2)}\times p_3^{max(k_3,j_3)}\times ...\times p_m^{max(k_m,j_m)} lcm(a,b)=p1max(k1,j1)×p2max(k2,j2)×p3max(k3,j3)×...×pmmax(km,jm)
上面的性质可以由2个推广到n个。
题解
这题显然是要求所有n以内,包含两个及以上不同质因子的数
的LCM。
根据上述性质,要求LCM,我们只需求出所有p的max值即可,显然,和2组合时,每个p可以取到max。
因此我们可以用欧拉筛筛出所有素数,然后对于每个素数,看能用2和最多几个该素数相乘得到。
2本身比较特殊,因为题目要求必须两个不同的质因子,所以计算2的贡献时,我们选用第二小的3即可。
还有一个小细节:
欧拉筛筛素数的时候,只需筛到n/2,因为(n/2,n]的素数肯定不可能和另一个素数(最小为2)相乘能得到n。
代码
/*
* @Author: hesorchen
* @Date: 2020-12-16 21:04:44
* @LastEditTime: 2021-02-02 20:18:51
* @Description: 栽种绝处的花
*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN 160000000
// #define MAXN 80000000 //只需筛到n/2
int preme[16000010], cot;
bool ispreme[160000010];
void pre()
{
ispreme[0] = ispreme[1] = 1;
for (int i = 2; i <= MAXN; i++)
{
if (!ispreme[i])
preme[++cot] = i;
for (int j = 1; j <= cot && preme[j] * i <= MAXN; j++)
{
ispreme[preme[j] * i] = 1;
if (i % preme[j] == 0)
break;
}
}
}
long long ans = 1, mod = 1000000007;
int main()
{
pre();
int n;
cin >> n;
long long temp = n / 3; //先特判质数2,用3组合最省
while (temp >= 2)
{
temp /= 2;
ans = (ans * 2) % mod;
}
for (int i = 2; i <= cot; i++)
{
long long temp = n / 2, f = 0;
while (temp >= preme[i])
{
f = 1;
temp /= preme[i];
ans = (ans * preme[i]) % mod;
}
if (!f)
break;
}
if (ans >= 6)
cout << ans << endl;
else
cout << "empty" << endl;
return 0;
}