赞
踩
有时间刷个水题,防止抑郁。
Codeforces Round #698 (Div. 1),A 题,https://codeforces.com/contest/1477/problem/A。
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.
Now, Nezzar wonders if it is possible to have his favorite number k k k on the board after applying above operation multiple times.
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.
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).
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
YES
YES
NO
YES
YES
NO
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:
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 可以进行以下操作任意次:
现在,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 这样的值。这就是裴蜀定理。
#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)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。