G - 最小公倍数 ACdream - 1732 【快速素数打表----呜呜】

本文介绍了一个计算从1到n的所有整数最小公倍数(LCM)的算法,并提供了一段C++代码实现。该算法适用于n范围在2到10^8之间的情况,通过预处理素数及其幂次来高效解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最小公倍数

Time Limit: 10000/5000MS (Java/Others)  Memory Limit: 262144/131072KB (Java/Others)
Problem Description
两个数的最小公倍数就是就是一个最小的可以被这两个数都整除的整数,当然多个数也有最小公倍数,我们现在就来计算一下1~n的最小公倍数是多少吧~
Input
第一行有个数字T.( T≤10000)表示有T组测试数据。 接下来有T行,每行有个整数n.( 2≤n≤10^8).
Output
输出 LCM(1,2,3,4,5,……,n-1, n)对2^32取模的值。
Sample Input
5
10
5
200
15
20
Sample Output
2520
60
2300527488
360360
232792560
Source
第九届北京化工大学程序设计竞赛
Manager


宝宝心好累-.-


代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL unsigned long long
bool tai[100010000];
unsigned int zhi1[5800000],yu[5770];
int main()
{
    int q,lp1=0,lp2=0,kp=0,wei,ji=0;
    memset(tai,true,sizeof(tai));
    LL pp,oo,er;
    er=1LL<<32;
    pp=1;
    yu[lp2++]=1;
    bool fafe=false;
    for (int i=2;i<=100000000;++i)//素数打表部分
    {
        if (tai[i]==true)
        {
            if (fafe)
            {
                pp=(pp*i)%er;
                if (lp2%1000==0)//大于10^4次方的每1000个打一个乘积表---
                {
                    yu[lp2/1000]=pp;
                }

                lp2++;
            }
            else if (lp1==1228)//小于10^4共1229个素数-.-
                fafe=true;
            zhi1[lp1++] = i;
        }
        for (int j=0;((j<lp1)&&((long long)i*zhi1[j]<=100000000));++j)
        {
            tai[i*zhi1[j]]=false;
            if (i%zhi1[j]==0) break;
        }
    }
    zhi1[lp1++]=999999999;
    int n;scanf("%d",&n);
    while (n--)
    {
        scanf("%d",&q);
        if (q==2)
        {
            printf("2\n");
            continue;
        }
        pp=1;
        for (int i=0;i<1229;i++)//求每个小于10^4次方的素数的最大可能幂-----------构成最小公倍数呀
        {
            if (zhi1[i]>q) break;
            oo=1;
            while (zhi1[i]<=q/oo)
            {
                oo*=zhi1[i];
            }
            pp=(pp*oo)%er;
        }
        wei=upper_bound(zhi1,zhi1+lp1,q)-zhi1;
        if (wei>1229)//求大于10^4次方的素数乘积
        {
            wei-=1229;
            pp=(pp*yu[wei/1000])%er;
            for (int i=wei/1000*1000+1229;i<=wei+1228;i++)
            {
                pp=(pp*zhi1[i])%er;
            }
        }
        printf("%llu\n",pp);
    }
    return 0;
}
/*
12
1000000
2000000
10000000
20000000
80000000
90000000
100000000

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值