51nod 1434 數論區間LCM問題
阿新 • • 發佈:2019-02-05
題意:
一個整數序列S的LCM(最小公倍數)是指最小的正整數X使得它是序列S中所有元素的倍數,那麼LCM(S)=X。
例如,LCM(2)=2,LCM(4,6)=12,LCM(1,2,3,4,5)=60。 現在給定一個整數N(1<=N<=1000000),需要找到一個整數M,滿足M>N,同時LCM(1,2,3,4,...,N-1,N) 整除 LCM(N+1,N+2,....,M-1,M),即LCM(N+1,N+2,....,M-1,M)是LCM(1,2,3,4,...,N-1,N) 的倍數.求最小的M值。 分析:51分類上說的是一個四級的演算法,然後就一直想啊想啊的。讓我們求1,2,3,,,,,n的lcm還是比較容易的,就是求解這個區間中的質數的最大倍數小於等於n的那些數,乘起來就可以得到lcm,當然了這一題我們不需要乘,只需要將這些數字都記錄寫來就可以了的。
我們不需要求出n,n+1....m的lcm,只需要保證這個lcm可以被前面的lcm整數就可以了,也就是可以整除前面記錄的所有值
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> using namespace std; int const maxn = 1000005 ; int flag ; //最大的質數 int num ; //質數的個數 int a[maxn]; bool prime[maxn]; void Prime() { memset(prime,true,sizeof(prime)); prime[0]=false; prime[1]=false; int i; for (i = 2;i*i <= maxn;i++) { if (prime[i]) { int j = i*2; while (j <= maxn) { prime[j]=false; j+=i; } } } } int main() { Prime(); int n; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(a,0,sizeof(a)); num = 2 ; flag = 0 ; for(int i = 1 ; i <= n ; i++) { if(prime[i]) { int ans = i ; while(ans<=n/i) { ans*=i; } cout<<ans<<endl; flag = (n/ans+1)*ans ; if(num<flag)num=flag; } //cout<<a[i]<<endl; } printf("%d\n",num); } return 0; }