Codeforces Round 1766 D

Codeforces Round 1766

Educational Codeforces Round 139 (Rated for Div. 2)


D. Lucky Chains

简要题意:

\(n\) 组数据 (\(1 \le n \le 10^6\)),每组输入两个数 \(x,y,(1\le x,y \le 10^7)\)

找一个最小的自然数 \(k\) ,使得 \(\gcd(x+k,y+k)\neq1\) ,如果找不到,输出 \(-1\)

Idea:

考虑 $x $ 和 \(y\) 的差 \(d\)

由题意,不妨设 \(m |(x+k)\)\(m|(y+k)\)

有整除的可见性,得到 \(m|(x+k-y-k)\)\(m|d\)

相当于在 \(d\) 的因子中找一个 \(m\) ,使得 \(k\) 最小。

形式化地,有

\[opt(x,y)=\min_{m|d}(x+m-1)/m*m-x \]

枚举 \(d\) 的因子 \(m\) ,我们得到了一种 \(O(n\sqrt{d})\) 的做法。

Solution:

上面的做法不能通过本题,考虑优化。

考虑 \(d\) 的两个质因子 \(p,t\) (假设有),发现 \(m\)\(p\)\(t\) 时的解肯定不劣于 \(m\)\(pt\) 时的,因为 \(pt|x+k\) 时同时满足 \(p|x+k\)\(t|x+k\) ,反之则不一定。所以只枚举 \(d\) 的质因数即可。

如果我们知道值域内每个数的一个质因数,则枚举 \(d\) 的质因子这一问题可以通过递归解决,时间复杂度 \(O(\log w)\) ( \(w\) 为值域,\(1 \le w \le 1e7\) ) 。

预处理值域内每个数的一个质因数可以通过埃氏筛解决,时间复杂度 \(O(w \log w)\)

至此,本问题在 \(O(w \log w + n \log w)\) 时间内解决。

Code:

代码很短。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+100;
int a[maxn];
void init(){
	for(int i=1;i<maxn;i++) a[i]=i;
	for(int i=2;i<maxn;i+=2){
		a[i]=2;
	}
	for(int i=3;i<maxn;i+=2){
		if(a[i]!=i){
			continue;
		}
		for(int j=3;i*j<maxn;j+=2){
			a[i*j]=i;
		}
	} 
} 
int opt(int x,int y){
	int d=y-x;
	int ans=1e9+100;
	if(d==1){
		return -1;
	}
	while(d>1){
		ans=min(ans,a[d]-x%a[d]);
		if(x%a[d]==0){
			ans=0;
			break;
		}
		d/=a[d];
	}
	return ans;
}
int main(){
	init();
	int t;
	scanf("%d",&t);
	int x,y;
	while(t--){
		scanf("%d%d",&x,&y);
		printf("%d\n",opt(x,y));
	}
	return 0;
}
posted @ 2022-12-15 15:57  ArizonaYYDS  阅读(48)  评论(0)    收藏  举报