Codeforces1154 G. Minimum Possible LCM(数论)

这篇博客介绍了一种解决寻找数组中最大最小公倍数问题的算法,复杂度为O(1e7*log),在4秒时限内可以完成。通过枚举并更新gcd(最大公约数)和下标,找到两个数使得它们的最小公倍数最大,并给出相应的下标作为答案。代码使用C++编写,展示了如何利用位运算和数组优化求解过程。
摘要由CSDN通过智能技术生成
题意:

在这里插入图片描述

解法:
用id[x]值为x的数的下标,
如果一个数x出现了两次,由于lcm(x,x)=x,那么可以直接用x更新答案.

[1,1e7]枚举gcd=g,然后枚举g的倍数,选择两个最小的g的倍数x和y,
那么lcm=x*y/g,然后更新答案即可.

复杂度O(1e7*log),这题4s时限,可以过.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e7+5;
int id[maxm];
int n;
void solve(){
    cin>>n;
    int mi=1e18;
    int ans1=1,ans2=2;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        if(id[x]&&x<mi)mi=x,ans1=id[x],ans2=i;
        id[x]=i;
    }
    for(int i=1;i<maxm&&i<mi;i++){//枚举gcd
        int val=0,pos=0;
        for(int j=i;j<maxm;j+=i){
            if(!id[j])continue;
            if(!pos)val=j,pos=id[j];
            else{
                if(val/i*j<mi)mi=val/i*j,ans1=pos,ans2=id[j];
                break;
            }
        }
    }
    if(ans1>ans2)swap(ans1,ans2);
    cout<<ans1<<' '<<ans2<<endl;
}
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);
    solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值