传送门
 

题意:个数中最小公倍数数值最小的两个数的下标。

参考博客:https://blog.csdn.net/qq_41157137/article/details/89353527

思路:

                                               

对于包含 的数  

如果 的最大公约数,那么一定小于,后面就可以不用考虑了

如果不是不是的最共公约数( 满足的因子,比如 )。那么  也一定小于

,如果的最大公约数,同样,后面就可以不用考虑了

所以我们只需要得到每个d的倍数的前2项即可,时间复杂度(1e7*log(le7))

代码:

///#include <bits/stdc++.h>
///#include <unordered_map>
///#include <unordered_set>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <new>
#include <ctime>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai = acos(-1.0);
const double E = exp(1.0);
const int INF = 0x3f3f3f3f;
const long long mod = 1e9 + 7;

int n, maxn, p1, p2, lcm[10000005], num[10000005];
ll ans_lcm = 1e18 + 7;
bool vis[10000005];

int main() {
    maxn = 0;
    memset(vis, false, sizeof(vis));
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &num[i]);
        maxn = max(maxn, num[i]);
        ///存在相同数字的情况
        if (vis[num[i]]) {
            if (ans_lcm > num[i]) {
                ans_lcm = num[i];
                p1 = i;
                p2 = lcm[num[i]];
            }
        } else
            vis[num[i]] = 1, lcm[num[i]] = i;
    }
    for (int i = 1; i <= maxn; i++) {///枚举公因子
        int pre = -1;
        for (int j = i; j <= maxn; j+=i) {///枚举数字
            if (vis[j] && pre == -1) {
                pre = j;
            } else if (vis[j] && pre != -1) {
                ll now_lcm = (ll) pre / __gcd(pre, j) * j;
                if (ans_lcm > now_lcm) {
                    ans_lcm = now_lcm;
                    p1 = lcm[pre];
                    p2 = lcm[j];
                }
                break;
            }
        }
    }
    printf("%d %d\n", min(p1, p2), max(p1, p2));
    return 0;
}