题意:
已知一个数集中有一些数,又知若(x,y)都在集合中,那么(2x-y)和(2y-x)也都在集合中,问(k)是否在集合中。
题解:
首先假设一开始集合中存在(0)。
那么每个数的任意倍数都在集合中。
至于证明,可以把(2x-y)看做(y)关于(x)做了对称,容易发现任意倍数可以被表出。
那么假如(k)能被这些数表出,根据裴蜀定理,(k)一定是全体数的(gcd)的倍数。
判断一下即可。
(0)不在集合内?
所有数包括(k)减去最小的那个数即可。
减去那个数相当于平移了(x_1)个单位,但是平移对对称操作没有影响,所以平移不会改变答案,所以可以平移。
#include <bits/stdc++.h>
#define int long long
#define Mid ((l + r) >> 1)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
int read(){
char c; int num, f = 1;
while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
return f * num;
}
const int N = 3e5 + 1009;
int n, k, a[N], g;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
void work() {
n = read(); k = read();
for(int i = 1; i <= n; i++) a[i] = read();
sort(a + 1, a + 1 + n);
for(int i = 2; i <= n; i++) a[i] -= a[1]; k -= a[1];
if(k < 0) k = -k;
g = a[2];
for(int i = 3; i <= n; i++)
g = gcd(g, a[i]);
printf("%s
", k % g == 0 ? "YES" : "NO");
}
signed main()
{
int Case = read();
while(Case--) work();
return 0;
}