题目
n(2<=n<=1e5)个数的数组a[],满足ai(1<=ai<=2e5)
求gcd({lcm({ai,aj}) | i
即对任意两个不同下标(i,j),求其最小公倍数lcm(i,j)
再对这C(n,2)个结果,求其最大公约数gcd
思路来源
题解
题解
1600的题也要总结,我也太废物了吧……
①一个比较直观好做的做法,枚举素因子pi,
考虑pi在至少n-1个数中都出现才可以被保留下来,否则两个pi的0次幂其gcd一定为1
如果在n个数中均出现,答案是次小的幂次,
如果在n-1个数中出现,说明最小的幂次是0,即
②真正想总结的是这个做法,
考虑n=3,
把含a1项搞出来,求个gcd,含a2项搞出来求个gcd,…,之后再两两求gcd
先给结论:
证这个结论,可以考虑对每个素因子证,gcd是对幂次取min,lcm是取max
等价于证
于是分还是大于,讨论一下就证完了
有了化简之后的式子,维护一个后缀gcd,就做完了
代码
#include
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define sci(a) scanf("%d",&(a))
typedef long long ll;
const int N=1e5+10;
ll lcm(ll x,ll y){
return x/__gcd(x,y)*y;
}
int n;
ll a[N],suf[N],ans;
int main(){
sci(n);
rep(i,1,n){
scanf("%lld",&a[i]);
}
suf[n]=a[n];
per(i,n-1,1){
suf[i]=__gcd(suf[i+1],a[i]);
}
ans=lcm(a[1],suf[2]);
rep(i,2,n-1){
ans=__gcd(ans,lcm(a[i],suf[i+1]));
}
printf("%lld\n",ans);
return 0;
}