链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1694
题意:给你一个N,让你LCM(1,2,3,...,N)除以N以内所有质数的积。
分析:我们知道这个LCM是N以内的所有质数最高次幂的积。
N<10e14,所以最大的素数不超过10e7,因为最大的质素不超过2次方,一次幂的会被除掉。
这里只剩下质数幂的积形式,所以每次只要碰到质数的幂就乘以这个质数。
我们可以预处理每个质数的幂,存下这个质数和它的幂,排个序后,我们可以连乘预处理上面所说的积改变过程。
然后二分求出小于N的最小质数的幂是第几个。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 10000000
#define Mm 670000
#define MM 1e14+5
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int prime[Mm],tot=0,no[Mn];
int a;
vector<pair<ll,int> > vt;
int ans[Mn];
void Prime() {
vt.push_back(make_pair(1,1));
for(int i=2;i<=Mn;i++) {
if(!no[i]) {
prime[++tot]=i;
for(double j=(double)i*i;j<MM;j*=i)
vt.push_back(make_pair((ll)j,i));
}
for(int j=1;prime[j]*i<=Mn;j++) {
no[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
sort(vt.begin(),vt.end());
ans[0]=1;
for(int i=1;i<vt.size();i++) {
ans[i]=((ll)ans[i-1]*vt[i].second)%mod;
}
}
int main() {
Prime();
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++) {
ll n;
scanf("%lld",&n);
int l=0,r=vt.size()-1;
while(l<r) {
int mid=(l+r+1)>>1;
if(vt[mid].first<=n) {
l=mid;
} else r=mid-1;
}
printf("Case %d: %d\n",cas,ans[l]);
}
}