链接: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]); } }