Codeforces 题解 —— Codeforces Round #698 (Div. 1) —— A. Nezzar and Board —— 裴蜀定理

有时间刷个水题,防止抑郁。

题目相关

题目链接

Codeforces Round #698 (Div. 1),A 题,https://codeforces.com/contest/1477/problem/A

Problem Statement

n n n distinct integers x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn are written on the board. Nezzar can perform the following operation multiple times.

  • Select two integers x , y x,y x,y (not necessarily distinct) on the board, and write down 2 x − y 2x−y 2xy. Note that you don’t remove selected numbers.

Now, Nezzar wonders if it is possible to have his favorite number k k k on the board after applying above operation multiple times.

Input

The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 5 1≤t≤10^5 1t105) — the number of test cases.
The first line of each test case contains two integers n , k n,k n,k ( 2 ≤ n ≤ 2 ⋅ 1 0 5 , − 1 0 18 ≤ k ≤ 1 0 18 2≤n≤2⋅10^5, −10^{18}≤k≤10^{18} 2n2105,1018k1018).
The second line of each test case contains n n n distinct integers x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn ( − 1 0 18 ≤ x i ≤ 1 0 18 −10^{18}≤x_i≤10^{18} 1018xi1018).
It is guaranteed that the sum of n n n for all test cases does not exceed 2 ⋅ 1 0 5 2⋅10^5 2105.

Output

For each test case, print “YES” on a single line if it is possible to have k k k on the board. Otherwise, print “NO”.
You can print each letter in any case (upper or lower).

Example

Input

6
2 1
1 2
3 0
2 3 7
2 -1
31415926 27182818
2 1000000000000000000
1 1000000000000000000
2 -1000000000000000000
-1000000000000000000 123
6 80
-5 -20 13 -14 -2 -11

Output

YES
YES
NO
YES
YES
NO

Note

In the first test case, the number 1 1 1 is already on the board.
In the second test case, Nezzar could perform the following operations to write down k = 0 k=0 k=0 on the board:

  • Select x = 3 x=3 x=3 and y = 2 y=2 y=2 and write down 4 4 4 on the board.
  • Select x = 4 x=4 x=4 and y = 7 y=7 y=7 and write down 1 1 1 on the board.
  • Select x = 1 x=1 x=1 and y = 2 y=2 y=2 and write down 0 on the board.

In the third test case, it is impossible to have the number k = − 1 k=−1 k=1 on the board.

题解报告

题目翻译

黑板上写着 n n n 个不同的整数 x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn。Nezzar 可以进行以下操作任意次:

  • 选择两个整数 x x x y y y,这两个整数不需要不同,计算出 2 x − y 2x-y 2xy 的结果。注意你不需要删除已经选中的数据。

现在,Nezzar 想知道,经过任意次操作后,是否可以获得他最喜欢的数字 k k k

题目分析

本题又是一个最大公约数(GCD)问题。就是求数列 x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn 的最大公约数,关于求数列最大公约数的分析,请参考 https://blog.csdn.net/justidle/article/details/112252780
根据题目的要求,我们从数列 x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn 中选出两个数 x x x y y y,进行 2 x − y 2x-y 2xy 的操作,最终得到的数要为 k k k。也就是意味着,经过了若干次(比如 m m m 次)操作,我们将得到 k k k。也就是意味着数列的 x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,,xn 的最大公约数 a n s − x 1 ans-x_1 ansx1 必须是 k k k 的倍数。

进一步解释

有人问为什么这样想。
首先,考虑知识点。看到题目,应该可以联想到到考点就是数列的 GCD。
其次,这题就是裴蜀定理。根据题目 g ∣ x , g ∣ y ⟹ g ∣ ( 2 x − y ) g|x,g|y⟹g|(2x−y) gx,gyg(2xy)。下面我们只需要证明如果 ∀ x \forall x x 可以被 g g g 整除,我们就可以在黑板上写出 x x x

裴蜀定理

在数论中,裴蜀定理(Bézout’s Theorem)是一个关于最大公约数(或最大公约式)的定理,裴蜀定理得名于法国数学家艾蒂安·裴蜀。裴蜀定理说明了对任何整数 a a a b b b 和它们的最大公约数 d d d ,关于未知数 x x x 以及 y y y 的线性的丢番图方程(称为裴蜀等式)。具体定理描述如下:
a 1 , a 2 , . . , a n a_1,a_2,..,a_n a1,a2,..,an n n n 个整数, d d d 是它们的最大公约数,那么存在整数 x 1 , . . . , x n x_1, ..., x_n x1,...,xn 使得 x 1 ∗ a 1 + x 2 ∗ a 2 + . . . x n ∗ a n = d x_1*a_1+x_2*a_2+...x_n*a_n=d x1a1+x2a2+...xnan=d
特别来说,如果 a 1 , a 2 , . . , a n a_1,a_2,..,a_n a1,a2,..,an 互质(不是两两互质),那么存在整数 x 1 , . . . , x n x_1, ..., x_n x1,...,xn 使得 x 1 ∗ a 1 + x 2 ∗ a 2 + . . . x n ∗ a n = 1 x_1*a_1+x_2*a_2+...x_n*a_n=1 x1a1+x2a2+...xnan=1
下面我们回到题目,题目的操作是 2 x − y 2x-y 2xy,我们来推导一下操作的过程:
1、第一次取 x x x y y y。这样我们得到 2 x − y 2x-y 2xy
2、第二次取 p p p q q q。结合第一次操作,我们可以得到 2 ∗ ( 2 x − y ) − ( 2 q − p ) 2*(2x-y)-(2q-p) 2(2xy)(2qp)
3、以此类推。
通过观察,可以发现,最终的系数和是 2 ∗ 1 − 1 2*1-1 211 这样的形式。也就是说,经过若干次操作,我们将最终得到 k − a i k-a_i kai 这样的值。这就是裴蜀定理。

CF 官方解释

AC 参考代码

#include <bits/stdc++.h>

using namespace std;

//如果提交到OJ,不要定义 __LOCAL
//#define __LOCAL
typedef long long ll;
const int MAXN=2e5+4;
ll a[MAXN];

int main() {
#ifndef __LOCAL
	//这部分代码需要提交到OJ,本地调试不使用
	//ios::sync_with_stdio(false);
	//cin.tie(0);
	//cout.tie(0);
#endif
	int t;
    scanf("%d", &t);
	//cin>>t;
	while (t--) {
		ll n,k;
        scanf("%lld %lld", &n, &k);
		//cin>>n>>k;

		for (int i=1; i<=n; i++) {
            scanf("%lld", &a[i]);
			//cin>>a[i];
		}

		//求gcd
		ll ans=0;
		for (int i=1; i<n; i++) {
			ans = __gcd(ans, a[i+1]-a[i]);
		}

		//判断关系
		if ((k-a[1])%ans == 0) {
            printf("YES\n");
			//cout<<"YES\n";
		} else {
            printf("NO\n");
			//cout<<"NO\n";
		}
	}

#ifdef __LOCAL
	//这部分代码不需要提交到OJ,本地调试使用
	system("pause");
#endif
	return 0;
}

在这里插入图片描述124 ms 是用 scanf 和 printf 的时间,218 ms 是用 cin 和 cout 快读的时间。

时间复杂度

O ( N ) O(N) O(N)

空间复杂度

O ( N ) O(N) O(N)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的老周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值