牛客寒假集训J题一群小青蛙呱蹦呱蹦呱

本文介绍了一种求解多个数的最小公倍数(LCM)的高效算法。通过质因数分解理论,利用欧拉筛法筛选素数,并计算特定范围内能够构成有效组合的最大质因数幂次。

题目链接

题目链接

求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;
}
参考资料
先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问决定。 举一个平方和的例子。 简单的平方和问 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值