题目大意
给你一个长度为 (n) 的集合 ({a_1 , a_2;...;a_n}),请你求出 (gcd{ ext{lcm}(a_i,a_j);|;i<j })
思路
众所周知,( ext{lcm}(a,b)=dfrac{a imes b}{gcd(a,b)})
所以原式可以化为 (gcd{ dfrac{a_i imes a_j}{gcd(a_i,a_j)};|;i < j })
把 (gcd(a_i,a_j)) 提出可得 (dfrac{gcd{ a_i imes a_j;|;i < j }}{gcd(a_1,a_2 ;...;a_n)})
(gcd(a_1,a_2 ;...;a_n)) 可以线性求出,那么问题就转化成了如何快速求 (gcd{ a_i imes a_j;|;i < j })
设我们每次枚举到第 (i) 个数 (a_i) 为 (x),那么可以将 (gcd{ x imes a_j;|;i < j }) 中的 (x) 提出,就可以得到 (x imes gcd(a_{i+1},a_{i+2};...;a_{n}))。
可以预处理出一个后缀 (gcd) ,然后枚举 (a_i) 计算答案即可。
时间复杂度:常数极小的 ( ext{O}(n log a_{max}))
记得开 ( ext{long long}) ((
Code
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL read()
{
LL ans=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
return ans*f;
}
const LL N=1e5+5;
LL n,a[N],b[N],ans;
int main()
{
n=read();
for(LL i=1;i<=n;++i)
a[i]=read();
for(LL i=n;i>=1;--i)
// 预处理后缀 gcd
b[i]=__gcd(b[i+1],a[i]);
for(LL i=1;i<=n;++i)
// 计算 gcd { ai , aj | i < j }
ans=__gcd(ans,a[i]*b[i+1]);
// 答案就是 gcd { ai , aj | i < j } / gcd ( a1 , a2 ... an )
printf("%lld
",ans/b[1]);
return 0;
}