题意:
给出一个序列,两两之间的最小公倍数可以组成一个集合,计算这个集合的最大公因数。
题解:
第三题一般不会涉及算法,还是要向二分或前缀和的方向想一下。对于a1与剩下所有的数组成的最小公倍数,可以推导出:
gcd(lcm(a1,a2),lcm(a1,a3)....lcm(a1,an)) = lcm(a1,gcd(a2,a3,...,an))。
对于每个数都是如此,所以我们求出每个序列后缀的gcd就可以了。
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+100; typedef long long ll; ll a[maxn]; ll t[maxn];//保存后缀gcd ll Lcm[maxn];//保存以每个数为起点的最小公倍数集合的最大公因数 int n; ll lcm (ll x,ll y) { return x*y/__gcd(x,y); } int main () { cin>>n; for (int i=1;i<=n;i++) scanf("%lld",&a[i]); t[n]=a[n]; for (int i=n-1;i>=1;i--) t[i]=__gcd(t[i+1],a[i]); for (int i=1;i<=n;i++) Lcm[i]=lcm(a[i],t[i+1]); ll ans=Lcm[1]; for (int i=2;i<=n;i++) ans=__gcd(ans,Lcm[i]); printf("%lld\n",ans); }