CF1350C-Orac and LCM (lcm和gcd的性质)

题目链接:https://codeforces.com/contest/1350/problem/C

思路:

关于lcm和gcd的一些性质:

对于两个整数x,y,他们的lcm为x和y的所有质因子取最大指数的积,

他们的gcd为x和y所有的质因子取最小指数的积,

题意为每对i,j(i<j)求出他们的最小公倍数,再对所有的最小公倍数求他们的最大公因数g

对于所有的质因子,如果该质因子出现的次数<n-1,那么必定存在i,j,使得他们的lcm分解

之后该质因子的指数为0。

在求最小公倍数的时候,我们发现最小的那个指数会被提升,所以最后求g的时候其实该质因子的指数为

倒数第二小的,例如我们对10,24,40,80求按题意变化后的最大公因数。

我们先对每个数进行分解:10=2*5,24=23*3,40=23*5,80=24*5

两两求最小公倍数之后:得到120,40,80,120,240,80

120=23*3*5240=24*3*5,此时2这个质因子的最小指数变成了3,原来是1,因为我们在求最小公倍数的时候

将指数进行了提升,所以最后求g的时候用的是倒数第二小的那个指数,注意,若该质因子出现的次数=n-1,那么

此时最小的指数为0

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const int INF =1e9;
ll a[MAXN],n;
ll visit[MAXN];
int prime[MAXN],cnt;int max_index;
bool notprime[MAXN];
void get_prime()
{
    for(int i=2; i<=200000; i++)
    {
        if(!notprime[i])
            prime[cnt++]=i;
        for(int j=0; j<cnt&&prime[j]*i<=200000; j++)
        {
            notprime[prime[j]*i]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
vector<int>v[MAXN];
ll qp(ll a,ll i)
{
    ll res = 1;
    while(i)
    {
        if(i&1)
            res*=a;
        a*=a;
        i>>=1;
    }
    return res;
}
void div(int x)
{
    for(int i=0;i<cnt;i++)
    {
        if(prime[i]*prime[i]>x)
            break;
        if(x%prime[i]==0)
        {
            int num=0;max_index=max(max_index,i);
            while(x%prime[i]==0)
            {
                x/=prime[i];num++;
            }
            v[prime[i]].push_back(num);
        }
    }
    if(x>1)v[x].push_back(1),max_index=max(max_index,x);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    get_prime();
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    for(int i=1; i<=n; i++)
    {
        div(a[i]);
    }
    ll ans=1;
    for(int i=0; i<=max_index; i++)
    {
        int s = v[prime[i]].size();
        if(s)
        {
            sort(v[prime[i]].begin(),v[prime[i]].end());
            if(s==n-1)
                ans*=qp(prime[i],v[prime[i]][0]);
            if(s==n)
                ans*=qp(prime[i],v[prime[i]][1]);
 
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2020-05-13 12:25  grass_lin  阅读(294)  评论(0编辑  收藏  举报