每日一题-数论
Codeforces edu round 139 D - Lucky Chains
问题描述
给正整数\(x, y(x<y)\), 如果\(gcd(x, y), gcd(x+1, y+1) \dots gcd(x+k, y+k)都为1\), 则称这些数为Lucky Chain, 求\(x, y\)最长的Lucky Chain的长度, 如果这条链可以无限长, 输出-1
数论
\[假设使Lucky Chain断开的第一个元素为x+k, y+k,\\
则x+k, y+k有公因子p.\\则有:\\
\begin{cases}
x+k=np\\
y+k=mp (n,m为整数)\\
\end{cases}\\
可化为:y-x=(m-n)p\\
则可以通过x,y的差值找到公因子p, 对(y-x)分解因数即可, \\若找到任意的p, 该p对应的Lucky Chain的长度就是p-a\%p \\
在预处理因子时, 可以使用线性筛, 只需记录每个数的一个因子\\
可以发现, 只有一种情况下, Lucky Chain无限长, 即x+1=y时\\
\]
代码
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 7;
int fac[N], prime[N], cnt;
bool st[N];
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
void solve() {
int x, y;
cin >> x >> y;
if (y - x == 1) {
cout << "-1\n";
return;
}
if (gcd(x, y) != 1) {
cout << "0\n";
return;
}
int ans = 1e9, dif = y - x;
while (dif > 1) {
int p = fac[dif];
dif /= p;
ans = min(ans, p - x % p);
}
cout << ans << '\n';
}
signed main() {
IOS;
int T;
cin >> T;
for (int i = 2; i <= 10000000; ++i) {
if (!st[i]) {
prime[cnt ++] = i;
fac[i] = i;
}
for (int j = 0; prime[j] <= 10000000 / i; ++j) {
st[prime[j] * i] = 1;
fac[prime[j] * i] = prime[j];
if (i % prime[j] == 0) {
break;
}
}
}
while (T--) {
solve();
}
return 0;
}
posted on 2022-12-13 17:06 Whosedream-0019 阅读(50) 评论(0) 收藏 举报
浙公网安备 33010602011771号