Codeforces Round #641 (Div. 1) A. Orac and LCM(數論 gcd與lcm性質)

題目

n(2<=n<=1e5)個數的數組a[],滿足ai(1<=ai<=2e5)

求gcd({lcm({ai,aj}) | i<j}),

即對任意兩個不同下標(i,j),求其最小公倍數lcm(i,j)

再對這C(n,2)個結果,求其最大公約數gcd

思路來源

題解

題解

1600的題也要總結,我也太廢物了吧……

①一個比較直觀好做的做法,枚舉素因子pi,

考慮pi在至少n-1個數中都出現纔可以被保留下來,否則兩個pi的0次冪其gcd一定爲1

如果在n個數中均出現,答案是次小的冪次,lcm(p_{i}^{first},p_{i}^{second}})=pi^{second}

如果在n-1個數中出現,說明最小的冪次是0,即lcm(pi^0,pi^{first})=pi^{first}

②真正想總結的是這個做法,

考慮n=3,gcd(lcm(a1,a2),lcm(a1,a3),lcm(a2,a3))=gcd(gcd(lcm(a1,a2),lcm(a1,a3)),gcd(lcm(a2,a3)))

把含a1項搞出來,求個gcd,含a2項搞出來求個gcd,…,之後再兩兩求gcd

先給結論:gcd(lcm(a1,a2),lcm(a1,a3),...,lcm(a1,an))=lcm(a1,gcd(a2,...,an))

證這個結論,可以考慮對每個素因子證,gcd是對冪次取min,lcm是取max

等價於證min(max(a1,a2),max(a1,a3),...,max(a1,an))=max(a1,min(a2,...,an))

於是分a1\leq min(a2,...,an)還是大於,討論一下就證完了

有了化簡之後的式子,維護一個後綴gcd,就做完了

代碼

#include<bits/stdc++.h>
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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章