LIGHT OJ 1289 LCM from 1 to n

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26999

题意:

给定一个n,求,LCM(1,2,3,.....,n)
分析:

几个数的最小公倍数等于这些数的素因子的最高次幂的乘积;

由于求1到n的所有的数的最小公倍数 ,所有的素因子为小于等于n的所有素数

因此我们至于要求出这些素数在n内的最高次幂即可。

我们可以先预处理出所有的素数的乘积,然后再乘上到n的p[i]最高次幂/p[i]。

因为是对2^32取模 我们可以用unsigned int来存。

还有一个困难时筛求素数的时候我们开不出那么大的数组 ,因此我们需要用到一个新的工具

位图,就不在这里讲解了。

位图的讲解:http://dongxicheng.org/structure/bitmap/

用位图筛素数的方法:http://blog.csdn.net/raomeng1/article/details/8520199

代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn =100000009;
typedef unsigned int UUI;
int vis[maxn/32+50];
UUI mul[5800000];
int p[5800000],cnt,n;


void init()//运用位图来筛素数+预处理素数的积
{
    cnt=1;
    p[0]=mul[0]=2;
    for(int i=3;i<maxn;i+=2){
        if(!(vis[i/32]&(1<<((i/2)%16)))){
            p[cnt]=i;
            mul[cnt]=mul[cnt-1]*i;
            cnt++;
            for(int j=i*3;j<maxn;j+=2*i)
                vis[j/32]|=(1<<((j/2)%16));
        }
    }
}

UUI solve()
{
    int pos=upper_bound(p,p+cnt,n)-p-1;//定位到第一个小于n的素数
    UUI ans = mul[pos];
    for(int i=0;i<cnt&&p[i]*p[i]<=n;i++){
        int tmp=p[i];
        int tt=p[i]*p[i];
        while(tt/tmp==p[i]&&tt<=n){//得到max(p[i]^k)<=n;用tmp*p[i]会爆int;
            tmp*=p[i];
            tt*=p[i];
        }
        ans*=(tmp/p[i]);
    }
    return ans;
}
int main()
{
    int t,cas=1;
    scanf("%d",&t);
    init();
    while(t--){
        scanf("%d",&n);
        printf ("Case %d: %u\n",cas++,solve());
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值