[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
", k % g == 0 ? "YES" : "NO");
}
signed main()
{
	int Case = read();
	while(Case--) work();
	return 0;
}
原文地址:https://www.cnblogs.com/onglublog/p/14375715.html