Codeforces Round #641 (Div. 2) C. Orac and LCM 题解(质因数分解+快速幂)

题目链接

题目思路

emm,感觉和hdw学长的题目极其类似,但是自己还是没想出来,其实就是分解一下,然后找次小。

因为 lcm的每个质因子的指数是这两个数的指数的max,然后lcm的gcd的指数是lcm里面指数的min

注意:我本来是外层枚举a[i],内层枚举质数,但是我发现这样根本不好break,会tle。外层枚举质数,内层枚举a[i]即可break

代码

#include
#include
#include
#include
#include
typedef long long ll;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
int n,a[maxn],mi1,mi2;//mi1最小,mi2次小
int isprime[maxn],prime[maxn],cnt;
ll ans=1;
int qpow(int a,int b){
    int base=a,ans=1;
    while(b>0){
        if(b&1){
            ans=ans*base;
        }
        base=base*base;
        b=b>>1;
    }
    return ans;
}
void getprime(){
    for(int i=2;i<=2e5;i++){//17984个质数
        if(!isprime[i]){
            for(ll j=1ll*i*i;j<=2e5;j=j+i){
                isprime[j]=1;
            }
            prime[++cnt]=i;
        }
    }
}
signed main(){
    getprime();
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    //外层枚举质数,内层枚举a[i]
    for(int j=1;j<=cnt;j++){
        mi1=mi2=0x3f3f3f3f;
        for(int i=1;i<=n;i++){
            int tot=0;
            while(a[i]%prime[j]==0){
                a[i]=a[i]/prime[j];
                tot++;
            }
            if(tot<=mi1){
                mi2=mi1;
                mi1=tot;
            }else if(tot<=mi2){
                mi2=tot;
            }
            if(mi2==0){
                break;
            }
        }
        ans=ans*qpow(prime[j],mi2);
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(数论)