题目链接:https://vjudge.net/contest/373416#problem/A
位图标记法:https://blog.youkuaiyun.com/acdreamers/article/details/18507767
题意:要求是让求1到n的最小公倍数。
思路:https://blog.youkuaiyun.com/qq_42815188/article/details/104328129
注:用二分查找节省时间,还有本题要求最终结果mod 2^32,可以借助 unsigned int 溢出时等价。
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
代码如下:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<bitset>
#include<algorithm>
using namespace std;
const int N=1e8+10;
bitset<N>book;
int su[5800000];//素数
unsigned int sum[5800000];//前缀积
int r=0;
void prime()//线性筛打表
{
for(int i=2; i<N; i++)
{
if(!book[i])
su[r++]=i;
for(int j=0; j<r&&i*su[j]<N; j++)
{
book[i*su[j]]=1;
if(i%su[j]==0)
break;
}
}
sum[0]=2;
for(int i=1; i<r; i++) //前缀积
sum[i]=sum[i-1]*su[i];
}
unsigned int qq(int x,int y)//快速幂
{
unsigned int res=1;
while(y)
{
if(y%2)
res*=x;
x*=x;
y/=2;
}
return res;
}
int main()
{
prime();
int t;
int o=1;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int id=upper_bound(su,su+r,n)-su;//找到第一个>n的素数位置
id-=1;//找到最大的那个比n小的素数
unsigned int ans=sum[id];
for(int i=0; i<r&&su[i]*su[i]<=n; i++)
{
int xx=n;
int num=0;
while(xx/su[i])//求su[i]的最高次幂
{
xx/=su[i];
num++;
}
num--;//前缀积里已经有一个了
ans*=qq(su[i],num);
}
printf("Case %d: %u\n",o++,ans);
}
return 0;
}