题目如下:
题解 or 思路:
g
c
d
(
a
,
b
)
=
g
c
d
(
a
,
a
−
b
)
gcd(a, b) = gcd(a, a - b)
gcd(a,b)=gcd(a,a−b)
题目要我们计算
g
c
d
(
a
+
k
,
b
+
k
)
=
1
gcd(a + k, b + k) = 1
gcd(a+k,b+k)=1 的最小
k
k
k 是多少
g
c
d
(
a
+
k
,
b
+
k
)
=
g
c
d
(
a
+
k
,
a
−
b
)
gcd(a + k, b + k) = gcd(a + k, a - b)
gcd(a+k,b+k)=gcd(a+k,a−b)
根据这个等式,问题就转换成:
设
d
i
f
dif
dif 等于
a
b
s
(
a
−
b
)
abs(a - b)
abs(a−b)
设
p
p
p 是
d
i
f
dif
dif 的一个质因子
我们要计算
p
−
a
%
p
p - a \% p
p−a%p 的最小值
AC代码
代码一:
线性筛 + 根号下暴力找质因子
const int N = 100009;
const int maxn = 3200;
int a, b;
int prime[N];
bool sf[N];
int num;
void sushu()
{
sf[1] = 1;
sf[0] = 1;
for (int i = 2; i <= maxn; i++)
{
if (!sf[i])
prime[++num] = i;
for (int j = 1; j <= num; j++)
{
if (i * prime[j] > maxn)
break;
sf[i * prime[j]] = 1;
if (i % prime[j] == 0)
break;
}
}
}
void solve()
{
cin >> a >> b;
int dif = abs(a - b);
if (dif == 1)
{
cout << "-1\n";
return;
}
if (__gcd(a, b) != 1)
{
cout << "0\n";
return;
}
int ans = 0x3f3f3f3f;
int idx = 1;
while (prime[idx] * prime[idx] <= dif)
{
if (dif % prime[idx] == 0)
{
ans = min(ans, prime[idx] - a % prime[idx]);
while (dif % prime[idx] == 0)
dif /= prime[idx];
}
idx++;
}
if (dif > 1)
ans = min(ans, dif - a % dif);
cout << ans << '\n';
}
int main()
{
buff;
sushu();
int _;
cin >> _;
while (_--)
solve();
}
代码二:
更改筛法,记录每一个数的最小质因子
速度更快 空间换时间
const int maxn = 1e7 + 5;
int prime[maxn], p[maxn], num;
void sushu()
{
p[0] = p[1] = -1;
for (int i = 2; i < maxn; i++)
{
if (!p[i])
prime[++num] = i, p[i] = i;
for (int j = 1; j <= num && prime[j] * i < maxn; j++)
{
p[i * prime[j]] = prime[j];
if (i % prime[j] == 0)
break;
}
}
}
void solve()
{
int a, b;
cin >> a >> b;
int dif = abs(a - b);
if (dif == 1)
{
cout << -1 << '\n';
return;
}
if (__gcd(a, b) != 1)
{
cout << 0 << '\n';
return;
}
int ans = 0x3f3f3f3f;
while (dif > 1)
{
ans = min(ans, p[dif] - a % p[dif]);
int tt = p[dif];
while (dif % tt == 0)
dif /= tt;
}
cout << ans << '\n';
}
int main()
{
buff;
sushu();
int _;
cin >> _;
while (_--)
solve();
}