有时间刷个水题,防止抑郁。
题目相关
题目链接
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 2x−y. 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
1≤t≤105) — 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}
2≤n≤2⋅105,−1018≤k≤1018).
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}
−1018≤xi≤1018).
It is guaranteed that the sum of
n
n
n for all test cases does not exceed
2
⋅
1
0
5
2⋅10^5
2⋅105.
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 2x−y 的结果。注意你不需要删除已经选中的数据。
现在,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
2x−y 的操作,最终得到的数要为
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
ans−x1 必须是
k
k
k 的倍数。
进一步解释
有人问为什么这样想。
首先,考虑知识点。看到题目,应该可以联想到到考点就是数列的 GCD。
其次,这题就是裴蜀定理。根据题目
g
∣
x
,
g
∣
y
⟹
g
∣
(
2
x
−
y
)
g|x,g|y⟹g|(2x−y)
g∣x,g∣y⟹g∣(2x−y)。下面我们只需要证明如果
∀
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
x1∗a1+x2∗a2+...xn∗an=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
x1∗a1+x2∗a2+...xn∗an=1。
下面我们回到题目,题目的操作是
2
x
−
y
2x-y
2x−y,我们来推导一下操作的过程:
1、第一次取
x
x
x 和
y
y
y。这样我们得到
2
x
−
y
2x-y
2x−y;
2、第二次取
p
p
p 和
q
q
q。结合第一次操作,我们可以得到
2
∗
(
2
x
−
y
)
−
(
2
q
−
p
)
2*(2x-y)-(2q-p)
2∗(2x−y)−(2q−p);
3、以此类推。
通过观察,可以发现,最终的系数和是
2
∗
1
−
1
2*1-1
2∗1−1 这样的形式。也就是说,经过若干次操作,我们将最终得到
k
−
a
i
k-a_i
k−ai 这样的值。这就是裴蜀定理。
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)。