CF - Orac and LCM

原题:Codeforces 1350 C

题意:求一个数组中所有前后两个元素的最小公倍数的最大公约数

分析:

样例2中,10要与24, 40, 80取最小公倍,24与40, 80, 40与80。

以10的这一组为例,因为要求出所有与10的最小公倍数,所以肯定包含10,可以直接留在求整体gcd的时候乘。剩下的后面的3个数,直接取其最大公约数,与10相乘即是10这一组数的最小公倍数。

因此,可以利用后缀数组,先求出a[i]后的数的gcd,存储在数组里。然后,将数组与a[i]取lcm,再用这个结果与答案ans做gcd处理。

题解:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e5+5;
ll a[N],g[N];//记得要开longlong

int main()
{
    //cout<<__gcd(0,2)<<endl;
    //才知道一个数和0取gcd结果是其本身-_-
    
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }

    //写一个后缀数组,记录a[i]后面的数的最大公约数
    for(int i=n;i>=1;i--)
    {
        g[i]=__gcd(a[i],g[i+1]);
    }

    //求每一组数的最小公倍数的最大公约数
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        ans=__gcd(ans,a[i]/__gcd(a[i],g[i+1])*g[i+1]);
    }

    cout<<ans;
    return 0;
}
posted @ 2021-05-20 21:51  AtomsH  阅读(58)  评论(0)    收藏  举报