题意:最初有n个数,每次操作可以选取两个数 x, y,将 2x - y 添加到数列里(x, y不擦除),问是否可以组合出数k
思路:
2x - y = x + (x - y),即每次操作相当于x + 任意差值的线性组合,可以发现a3 - a1 = (a3 - a2) + (a2 - a1),不相邻的两个数的差值可以由相邻的数的差值表示出来,所以只求相邻两数的差值即可。
由n个数的裴蜀定理:
可知这n - 1个差值能组合出的数一定是它们gcd的倍数,即 (k - a[i])一定是gcd的倍数,由于原数列中的任何一个数都可以由a[1] + 差值表示出来,所以只判断a[1]即可。
参考:https://blog.csdn.net/kaka03200/article/details/113384470
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int N = 2e5 + 7;
ll a[N];
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
int main() {
int t, n;
ll k;
scanf("%d", &t);
while(t--) {
scanf("%d%lld", &n, &k);
ll gd;
for(int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
if(i == 1) continue;
else if(i == 2) gd = a[i] - a[i - 1];
else gd = gcd(gd, a[i] - a[i - 1]);
}
if((k - a[1]) % gd == 0) printf("YES\n");
else printf("NO\n");
}
return 0;
}