G. Minimum Possible LCM
题意:求 n n n个数中最小公倍数数值最小的两个数的下标。
题解:参考于https://blog.csdn.net/qq_41157137/article/details/89353527,因为
L
C
M
(
x
,
y
)
=
x
×
y
g
c
d
(
x
,
y
)
LCM(x,y) = \frac{x\times y}{gcd(x,y)}
LCM(x,y)=gcd(x,y)x×y
对于包含
d
=
g
c
d
(
x
,
y
)
d = gcd(x,y)
d=gcd(x,y)的数
x
1
,
x
2
,
x
3
.
.
.
x
i
(
x
1
<
x
2
<
x
3
.
.
.
x
i
)
x_1,x_2,x_3...x_i(x_1 <x_2<x_3...x_i)
x1,x2,x3...xi(x1<x2<x3...xi)
如果
d
d
d是
x
1
,
x
2
x_1,x_2
x1,x2的最大公因数,那么
l
c
m
(
x
1
,
x
2
)
lcm(x_1,x_2)
lcm(x1,x2)一定小于
x
1
×
x
3
d
\frac{x_1\times x_3}{d}
dx1×x3,剩下亦是如此;
如果
d
d
d不是
x
1
,
x
2
x_1,x_2
x1,x2的最大公因数,那么
l
c
m
(
x
1
,
x
2
)
lcm(x_1,x_2)
lcm(x1,x2)也一定小于
x
1
×
x
2
d
\frac{x_1\times x_2}{d}
dx1×x2,如果
d
d
d是
x
1
,
x
4
x_1,x_4
x1,x4的最大公因数,同样满足
l
c
m
(
x
1
,
x
2
)
<
x
1
×
x
4
d
lcm(x_1,x_2)<\frac{x_1\times x_4}{d}
lcm(x1,x2)<dx1×x4。
所以综上所述,只需要枚举最大公因数 d d d,然后取包含前两项的 a i a_i ai并且最后取 m i n min min即可。
代码
#include<bits/stdc++.h>
#define DEBUG(x) std::cerr << #x << '=' << (x) << std::endl
typedef long long LL;
using namespace std;
constexpr int N = 1E7+10;
int pos[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
ios::sync_with_stdio(false); cin.tie(nullptr);
int n, v, xi = 0, yi = 0;
cin >> n;
LL ret = LLONG_MAX;
for(int i = 1; i <= n; ++i) {
cin >> v;
if(pos[v] && v < ret) {
ret = v; //相同的数lcm肯定就是本身啦
xi = pos[v];
yi = i;
}
pos[v] = i;
}
for(int d = 1; d < N; ++d) {
for(int x = 0, y = d; y < N; y += d) {
if (pos[y]) { //因子包含d的数
if (x == 0) { x = y; }
else if (ret > 1LL * x * y / d) ret = 1LL * x * y / d, xi = pos[x], yi = pos[y];
}
}
}
if(xi > yi) swap(xi, yi);
cout << xi << ' ' << yi << endl;
return 0;
}