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;
}