codeforces 题目 Lucky Chains

目录

题目:

题目描述:

思路:

AC代码:


题目:

题目描述:

n个案例,每个案例给你一对( x ,y ),请找到最小的 k 使得 gcd( x + k ,y + k )> 1

思路:

gcd性质:

gcd( a , b )  ==  gcd( a , b - a )

  所以:

gcd( x + k , y + k ) == gcd( x + k , y - x )

那么问题就转化成了,如何找到最小的 k ,使得 gcd( x + k , y - x ) > 1

因为 y - x 是一个固定的值,所以此时我们可以枚举 y - x 这个值的所有质因子来作为成为二者的最大公因数,也就是 gcd( x + k , y - x ) 的值,然后对所有枚举的情况中的 k 取最小即可。

至于怎么快速多次的寻找 y - x 的最小质因子,我们可以先初始化一个欧拉筛,然后用一个数组存下所有范围内的数的最小质因数。

思路有了,具体操作请看AC代码

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 1e7 + 7;
const ll inf = 4e18 + 5;

ll prime[N];//质数数组
ll lp[N];//存放的是当前下标除1以外的最小因子

ll cnt = 1;
//欧拉筛
void init(int x)
{
	for (int i = 2; i <= x; i++)
	{
		if (lp[i] == 0)
		{
			prime[cnt++] = i;
			lp[i] = i;
		}
		for (int j = 1; j < cnt && prime[j] * i <= x; j++)
		{
			lp[prime[j] * i] = prime[j];
			if (prime[j] % i == 0)//保证每个合数都是由最小的质因子一遍筛掉
				break;
		}
	}
}

int main()
{
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	init(N - 1);

	ll n;
	cin >> n;

	while (n--)
	{
		ll a, b;
		cin >> a >> b;
        ll c = a - b;

		if (b > a)
			swap(a, b);

		if (c == 1)
		{
			cout << -1 << "\n";
			continue;
		}

		ll minn = inf;

		while (c > 1)
		{
			int temp = lp[c];
            //下面一行右半部分,意在寻找,x最少加多少能到temp的倍数
			minn = min(minn, temp - ((a - 1) % temp + 1));//寻找最小的 k

			while (c % temp == 0)
			    c /= temp;
		}
		cout << minn << '\n';
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值