Given an integer n, you have to find
lcm(1, 2, 3, ..., n)
lcm means least common multiple. For example lcm(2, 5, 4) = 20, lcm(3, 9) = 9, lcm(6, 8, 12) = 24.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing an integer n (2 ≤ n ≤ 108).
Output
For each case, print the case number and lcm(1, 2, 3, ..., n). As the result can be very big, print the result modulo 232.
Sample Input
5
10
5
200
15
20
Sample Output
Case 1: 2520
Case 2: 60
Case 3: 2300527488
Case 4: 360360
Case 5: 232792560
参考博客:https://blog.csdn.net/whyorwhnt/article/details/9397289
就是先累乘出素数的前缀和,然后找到比n小的第一个素数。然后就枚举那个素数(<n)然后看他的次方是否满足。
然后用ASN乘起来这个数。
#include<bits/stdc++.h>
using namespace std;
const int N=100000066;
int visit[N/32+50];
unsigned int data[5800000];
int prime[5800000],np=0;
void Prime () //筛素数,数组从0开始
{
prime[0]=data[0]=2;
np=1;
for (int i=3;i<N;i+=2) //扫所有奇数
if (!(visit[i/32] & (1 << ((i/2)%16))))
{
prime[np]=i;
data[np]=data[np-1]*i; //预处理
np++;
for (int j=3*i;j<N;j+=2*i) //改成i*i会超int范围
visit[j/32] |= (1 << ((j/2)%16));
}
}
unsigned int Deal (int n)
{
int p=upper_bound (prime, prime+np, n)-prime-1; //定位比n小的第一个素数
unsigned int ans = data[p];
//cout<<ans<<"ans"<<endl;
for (int i=0; i<np && prime[i]*prime[i] <= n; i++)//此时prime[i]最多10^4
{//扫所有素数的整数次幂
int mul = prime[i];//对于每一个素数
int tmp = prime[i] * prime[i];//它的平方
while (tmp/mul == prime[i] && tmp<=n) //防止int越界
{
tmp *= prime[i];//
mul *= prime[i];
}
ans *= (mul/prime[i]);
//这里是看几的次方为一个素数,再乘上就可以了。
//cout<<ans<<"ans111111"<<endl;
}
return ans;
}
int main ()
{
int T,n;
scanf("%d",&T);
Prime ();
for (int Cas=1;Cas<=T;Cas++)
{
scanf ("%d",&n);
printf ("Case %d: %u\n",Cas,Deal(n));
}
return 0;
}