题目链接:https://codeforces.com/contest/1350/problem/C
思路:
关于lcm和gcd的一些性质:
对于两个整数x,y,他们的lcm为x和y的所有质因子取最大指数的积,
他们的gcd为x和y所有的质因子取最小指数的积,
题意为每对i,j(i<j)求出他们的最小公倍数,再对所有的最小公倍数求他们的最大公因数g
对于所有的质因子,如果该质因子出现的次数<n-1,那么必定存在i,j,使得他们的lcm分解
之后该质因子的指数为0。
在求最小公倍数的时候,我们发现最小的那个指数会被提升,所以最后求g的时候其实该质因子的指数为
倒数第二小的,例如我们对10,24,40,80求按题意变化后的最大公因数。
我们先对每个数进行分解:10=2*5,24=23*3,40=23*5,80=24*5
两两求最小公倍数之后:得到120,40,80,120,240,80
120=23*3*5,240=24*3*5,此时2这个质因子的最小指数变成了3,原来是1,因为我们在求最小公倍数的时候
将指数进行了提升,所以最后求g的时候用的是倒数第二小的那个指数,注意,若该质因子出现的次数=n-1,那么
此时最小的指数为0
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=2e5+5; const int INF =1e9; ll a[MAXN],n; ll visit[MAXN]; int prime[MAXN],cnt;int max_index; bool notprime[MAXN]; void get_prime() { for(int i=2; i<=200000; i++) { if(!notprime[i]) prime[cnt++]=i; for(int j=0; j<cnt&&prime[j]*i<=200000; j++) { notprime[prime[j]*i]=1; if(i%prime[j]==0) break; } } } vector<int>v[MAXN]; ll qp(ll a,ll i) { ll res = 1; while(i) { if(i&1) res*=a; a*=a; i>>=1; } return res; } void div(int x) { for(int i=0;i<cnt;i++) { if(prime[i]*prime[i]>x) break; if(x%prime[i]==0) { int num=0;max_index=max(max_index,i); while(x%prime[i]==0) { x/=prime[i];num++; } v[prime[i]].push_back(num); } } if(x>1)v[x].push_back(1),max_index=max(max_index,x); } int main() { ios::sync_with_stdio(false); cin.tie(0); get_prime(); cin>>n; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++) { div(a[i]); } ll ans=1; for(int i=0; i<=max_index; i++) { int s = v[prime[i]].size(); if(s) { sort(v[prime[i]].begin(),v[prime[i]].end()); if(s==n-1) ans*=qp(prime[i],v[prime[i]][0]); if(s==n) ans*=qp(prime[i],v[prime[i]][1]); } } cout<<ans<<endl; return 0; }