Codeforces(C. Orac and LCM)数论

上一次打是4月20几号,期间鸽了好多场,加上期间也渐渐松懈了,没怎么做题,昨晚这场状态直接爆炸
这道题我现在知道两种做法,最好想的感觉就是分解质因数了,比赛时候不知为啥没想到这个点,等到快结束了才反应过来。
将每个数的质因数分解出来,其中质因数被包含n-1次及以上才能对最后的gcd产生贡献,贡献为该质因数倒数第二小的指数大小。
代码:

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

ll prime[200005],p[800005],cnt,sum[200005];
ll a[200005];
ll c[200005],d[200005][5];
void euler(int n)
{
    
    
    for(int i=2;i<=n;i++)
    {
    
    
        if(!p[i])
        {
    
    prime[++cnt]=i;sum[i]=1;}
        for(int j=1;j<=cnt;j++)
        {
    
    
            if(i*prime[j]>n)
            {
    
    break;}
            p[prime[j]*i]=1;
            if(i%prime[j]==0)
            {
    
    break;}
        }
    }
    for(int i=1;i<=200002;i++)
    {
    
    d[i][1]=99999999;d[i][2]=99999999;}
}
ll apow(ll a,ll b)
{
    
    ll s=1;while(b){
    
    if(b&1){
    
    s=s*a;}a=a*a;b>>=1;}return s;}
int main()
{
    
    
    ll t,n,m,flag=0,j,op;
    euler(200000);
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
    
    scanf("%lld",&a[i]);}
    if(n==2)
    {
    
    printf("%lld\n",(a[1]*a[2])/__gcd(a[1],a[2]));return 0;}
    for(int i=1;i<=n;i++)
    {
    
    
        m=a[i];j=1;
        if(sum[m]==1)
        {
    
    
            c[m]++;
            if(1<=d[m][1])
            {
    
    d[m][2]=d[m][1];d[m][1]=1;}
            else
            {
    
    
                if(1<=d[m][2])
                {
    
    d[m][2]=1;}
            }
            continue;
        }
        while(m>1)
        {
    
    
            op=0;
            if(m%prime[j]==0)
            {
    
    
                c[prime[j]]++;
                while(m%prime[j]==0)
                {
    
    m/=prime[j];
                op++;}
                if(op<=d[prime[j]][1])
                {
    
    
                    d[prime[j]][2]=d[prime[j]][1];
                    d[prime[j]][1]=op;
                }
                else
                {
    
    
                    if(op<d[prime[j]][2])
                    {
    
    d[prime[j]][2]=op;}
                }
                j++;
            }
            else
            {
    
    j++;}
        }
    }
    ll ans=1; 
    for(int i=1;i<=cnt;i++)
    {
    
    
        if(c[prime[i]]==n-1)
        {
    
    ans*=apow(prime[i],d[prime[i]][1]);}
        if(c[prime[i]]==n)
        {
    
    ans*=apow(prime[i],d[prime[i]][2]);}
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106093739