[CF]1478D Nezzar and Board
题意:
已知一个数集中有一些数,又知若\(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\n", k % g == 0 ? "YES" : "NO");
}
signed main()
{
int Case = read();
while(Case--) work();
return 0;
}