题目链接
题意:求gcd{lcm(a【i】,a【j】} i<j
思路:不知道正解是啥,就写一下比赛时的思路,感觉比D题还难呀。
右唯一分解定理知最后的答案一定和素因子之间的乘积,于是考虑一下素因子的贡献,先打表素数表,然后对于每个a【i】分解质因子,那么什么情况下素因子能产生贡献呢?只有含有素因子的个数等于n或者n-1的时候,个数等于n的时候很容易知道lcm会约去最小的那个,于是贡献就是g【t】【1】,那等于n-1的时候为什么也成立呢,因为数组a中如果只有一个数没有这个素因子的话,那么假设这个数为a【i】,a【i】与a【j】(i不等于j)的lcm中必定包含这个素因子。比如说3 2 8,3不含2这个素因子,但是lcm(3,2),lcm(3,8)会产生2这个因子,于是贡献就是g【t】【0】了,g【i】存的是含有素因子i的数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+1;
vector<int>g[maxn];
ll a[maxn];
int top=0,prime[maxn],isprime[maxn];
void Prime(int n)
{
for(int i=2;i<=n;++i)
{
if(!isprime[i]) prime[top++]=i;
for(int j=0;j<top;++j)
{
if(i*prime[j]>n) break;
isprime[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
void update(ll x)
{
for(int j=0;j<top;++j)
{
if(1LL*prime[j]*prime[j]>x) break;
if(x%prime[j]==0)
{
int cnt=0;
while(x%prime[j]==0)
{
cnt++;
x/=prime[j];
}
g[prime[j]].push_back(cnt);
}
}
if(x>1) g[x].push_back(1);
}
int main()
{
int T,n;
Prime(2e5);
cin>>n;
ll ans=1;
for(int i=1;i<=n;++i)
{
scanf("%lld",&a[i]);
update(a[i]);
}
for(int i=0;i<top;++i)
{
int t=prime[i],k=0;
sort(g[t].begin(),g[t].end());
if(g[t].size()==n) k=g[t][1];
if(g[t].size()==n-1) k=g[t][0];
for(int j=1;j<=k;++j) ans*=t;
}
cout<<ans<<endl;
}