LightOJ 1289 LCM from 1 to n

题意:

lcm(1,2,....n)
数据范围:
n108 , 104 组测试数据

思路:

L(2) = 1 * 2
L(3) = 1 * 2 * 3
L(4) = 1 * 2 * 3 * 2 // because 4 = 2^2
L(5) = 1 * 2 * 3 * 2 * 5
L(6) = 1 * 2 * 3 * 2 * 5 // 6 is not a perfect power of a prime
L(7) = ….
所以我们可以看出,计算lcm的时候,不断乘过去的时候,只有当乘数为素数的 整数 次幂时,才会增大答案,所以做法就很简单了!
预处理( 1108 )素数的前缀积,二分找到这个答案,然后更新答案!
比如 x=10 的话, ans=2357 (素数前缀积)
然后用素数 2,3 来更新答案(注意大于 x 的素数是不会更新答案的),所以 ans=ans231321

这样明显是不够的,MLE
首先是尝试去块处理前缀乘积,缩小内存,还是MLE
然后灵机一动,flag 数组这个改为 bitset 实现,因为bitset内部本质就是采用位图来搞的!终于AC!

代码:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned int UI;
const int N = 1e8 + 10;
const int BASE = 100;
int cnt, prime[5761460];
bitset<N> flag;
UI f[5761460/BASE];
void init()
{
    int i, j;
    cnt = 0;
    for(int i = 2;i < N;i ++)
    {
        if(!flag[i]) prime[cnt ++] = i;
        for(j = 0;j < cnt && i * prime[j] < N;j ++) {
            flag[i * prime[j]] = 1;
            if(i % prime[j] == 0) break;
        }
    }
    UI tmp = 1u;
    f[0] = 1u;
    for(int i = 0;i < cnt;i ++) {
        tmp = tmp * (UI)prime[i];
        if((i+1) % BASE == 0) f[(i+1)/BASE] = tmp;
    }
}

int main()
{
    int T, ca = 0;
    scanf("%d", &T);
    init();
    while(T --)
    {
        int n;
        scanf("%d", &n);
        int p = lower_bound(prime, prime + cnt, n) - prime;
        if(prime[p] > n) p --;
        UI ans = f[(p + 1)/BASE];
        for(int i = (p+1)/BASE * BASE;i <= p;i ++) ans = ans * (UI)prime[i];
        for(int i = 0;1LL * prime[i] * prime[i] <= n;i ++)
        {
            int cnt = 0, tmp = n;
            while(tmp >= prime[i]) cnt ++, tmp /= prime[i];
            for(int j = 2;j <= cnt;j ++) ans = ans * (UI)prime[i];
        }
        printf("Case %d: %u\n", ++ca, ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值