Codeforces Round #698 (Div. 2) D. Nezzar and Board(裴蜀定理)

https://codeforces.ml/contest/1478/problem/D

inline ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a % b);
}


//每次操作为在序列中任取两个数x, y(可以相同),将2x-y放入序列中,原x,y仍保留,询问是否可以凑出k
//假设一开始序列里有x,y,z,f,g
//那么我们来看每次操作得到的值
//第一次放入了(2x-y)
//第二次放入的可能是(2 *(2*x-y)-z)、(2 * f - g)或者(2 * f - (2*x - y)) 等等,不管怎么组合,在每一次操作后,得到的表达式的系数和都是1
//我们知道两个系数和是1的表达式f1, f2做(2 * f1 - f2)操作最终得到的表达式系数和仍是1
//那么所有可得到的表达式都可以表示为  任意的的(a[i]-a[j])* x 最后再加上任意一个a[i]使表达式系数和为1
//而对于所有的a[i]-a[j]有n^2种组合,但是我们可以通过 n-1个(a[i]-a[i-1])凑出这些组合
//所有最终目的就是能否通过这 n-1个值相加减得到 k-a[i]
//有裴蜀定理 对a[1]....a[n] n个整数和它们的最大公约数g,一定有x[1]..x[n],使a[1]*x[1] + a[2]*x[2] + ..... = g
//所有求出这n-1个数的gcd,看是否有k-a[i] % gcd == 0
ll a[maxn];
signed main() {
	begin();
	ll t; read(t);
	while (t--) {
		ll n, k;
		read(n); read(k);
		for (int i = 0; i < n; ++i)	read(a[i]);
		ll g = a[1] - a[0]; bool flag = 0;
		for (int i = 2; i < n; ++i)	g = gcd(g, a[i] - a[i - 1]);
		for (int i = 0; i < n; ++i)	if ((k - a[i]) % g == 0) {
			flag = 1; break;
		}
		puts(flag ? "YES" : "NO");
	}
	return 0;
}

posted @ 2021-03-05 10:26  wansheking  阅读(319)  评论(0)    收藏  举报