分析:考虑从1到n所有数的质因数分解,记录每个质数的最高次数,同理从n+1循环到2n,如果循环到m时每个质因子的次数都不低于所记录的,则跳出循环,结果即为m。先预处理质数,复杂度为O(nlongn)。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1000005; 7 int prinum[maxn],len=0,n,m,power[maxn],order[maxn]; 8 int num[maxn]; 9 void CalPri(){ 10 memset(order,-1,sizeof(order)); 11 for(int i=0;i<maxn;i++)num[i]=i; 12 for(int i=2;i<maxn;i++){ 13 if(num[i]==0)continue; 14 prinum[len++]=i; 15 order[i]=len-1; 16 for(int j=2*i;j<maxn;j+=i){ 17 num[j]=0; 18 } 19 } 20 } 21 int solve(){ 22 int countp=0; 23 if(order[n]!=-1)return 2*n; 24 memset(power,0,sizeof(power)); 25 for(int k=0;k<len&&prinum[k]<=n;k++){ 26 long long p=prinum[k],p0=prinum[k]; 27 countp++; 28 while(p<=n){ 29 p*=p0; 30 power[k]++; 31 } 32 // int k0=k; 33 // for(int i=0;i<len&&prinum[i]*prinum[i]<=k0;i++){ 34 // if(k0%prinum[i])continue; 35 // int p=prinum[i],cnt=0; 36 // if(power[i]==0)countp++; 37 // while(k0%p==0){ 38 // k0/=p;cnt++; 39 // } 40 // power[i]=max(cnt,power[i]); 41 // } 42 // if(k0!=1){ 43 // if(power[order[k0]]==0)countp++; 44 // power[order[k0]]=max(1,power[order[k0]]); 45 // } 46 } 47 for(int k=n+1;k<=2*n;k++){ 48 int k0=k; 49 for(int i=0;i<len&&prinum[i]*prinum[i]<=k0;i++){ 50 if(k0%prinum[i])continue; 51 int p=prinum[i],cnt=0; 52 while(k0%p==0){ 53 k0/=p;cnt++; 54 } 55 if(power[i]>0&&power[i]<=cnt){ 56 countp--; 57 power[i]=0; 58 } 59 } 60 if(k0!=1&&power[order[k0]]==1){ 61 countp--;power[order[k0]]=0; 62 } 63 if(!countp){ 64 return k; 65 } 66 } 67 } 68 int main(){ 69 //freopen("e:\in.txt","w",stdout); 70 CalPri(); 71 int t; 72 cin>>t; 73 while(t--){ 74 cin>>n; 75 cout<<solve()<<endl; 76 } 77 return 0; 78 }