[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;
}
posted @ 2021-02-05 01:02  _onglu  阅读(70)  评论(0编辑  收藏  举报