每日一题-数论

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)    收藏  举报

导航