求LCM(1-n)

#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long

using  namespace std;

const int maxn=1e8+10;
const int maxm=6e6+10;

int cnt=0;
int prime[maxm];
int vis[(maxn>>5)+10];
unsigned int sum[maxm];

void set_bit(int x)
{
    vis[x>>5] |= (1<<(x%32));
}

bool check_bit(int x)
{
    return vis[x>>5] & (1<<(x%32));
}

void get_prime()
{
    int side=sqrt(maxn+0.5);
    for(int i=2;i<=side;i++)
    {
        if(!check_bit(i))
        {
            prime[++cnt]=i;
            for(int j=i*i;j<=maxn;j+=i)
            {
                set_bit(j);
            }
        }
    }
    for(int i=side+1;i<=maxn;i++)
    {
        if(!check_bit(i))
        {
            prime[++cnt]=i;
        }
    }
}

void Init()
{
    sum[0]=1;
    for(int i=1;i<=cnt;i++)
    {
        sum[i]=sum[i-1]*prime[i];
    }
}

int main()
{
    int T,n;
    scanf("%d",&T);
    get_prime();
    Init();
    for(int k=1;k<=T;k++)
    {
        scanf("%d",&n);
        int p=upper_bound(prime+1,prime+cnt+1,n)-prime-1;
        unsigned ans=sum[p];
        for(int i=1;i<=cnt&&prime[i]*prime[i]<=n;i++)
        {
            int mul=prime[i];
            int tmp=prime[i]*prime[i];
            while(tmp/mul==prime[i]&&tmp<=n)
            {
                tmp*=prime[i];
                mul*=prime[i];
            }
            ans*=(mul/prime[i]);
        }
        printf("Case %d: %u\n",k,ans);
    }
    return 0;
}

  用位图进行素数筛,节省空间。

  unsigned int 自动取余(2的32次方)
 
 记录素数的前缀积,然后进行计算

 求法
L(1) = 1

L(x+1) = { L(x) * p    if x+1 is a perfect power of prime p
         { L(x)        otherwise

猜你喜欢

转载自www.cnblogs.com/pzh2019/p/11348294.html
今日推荐