51nod 1434 理解lcm
收藏
关注
一个整数序列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值。
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 每组测试数据有相同的结构构成: 每组数据一行一个整数N,1<=N<=1000000。
Output
每组数据一行输出,即M的最小值。
Input示例
3 1 2 3
Output示例
2
4
4
6
lcm是最小公倍数。2个数的最小公倍数代表着什么呢? 其实就是2个数他们的质因子一定有公有部分(有的只有1)。
那么公有部分只需要取一次,其它非公有的都相乘,这个数就是最小公倍数。所以这里就是要找到一个m,使m尽量小,
让m都包含1~n里所有质因子的最高次方,这时候只需要对于每一个质因子,找到x,使x*prime[i](当前质因子) <= n,
然后x乘上最小的一个值后,x > n,这是候这个x就是满足的其中一个值。这是只需要遍历一下所有情况就能得到最小的m。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<string> #include<time.h> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 1<<30 #define ll unsigned long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define MOD 1000000007 using namespace std; const int MAXN = 1000010; ll n; int a[MAXN],cnt,numa[MAXN]; int isnotprime[MAXN],num; ll prime[MAXN]; void Init() { num = 0; memset(isnotprime,0,sizeof(isnotprime)); for(int i = 2; i <= MAXN - 5; i++){ if(!isnotprime[i]){ prime[num++] = i; } for(int j = 0; j < num && 1LL * i * prime[j] < MAXN; j++){ isnotprime[i*prime[j]] = 1; if(i % prime[j] == 0)break; } } } void solve() { if(n == 1){ cout<<2<<endl; return ; } ll ans = 0; for(int i = 0; i < num; i++){ if(prime[i] > n)break; ll ret = 1; while(ret * prime[i] <= n){ ret *= prime[i]; } for(int j = 2; ; j++){ if(ret * j > n){ ret *= j; break; } } ans = max(ans,ret); } cout<<ans<<endl; } int main() { int t; scanf("%d",&t); Init(); while(t--){ scanf("%d",&n); solve(); } return 0; }