赞
踩
给出n个数,每次可以从序列中任意取出两个数x,y(x,y)可以相同,将2*x-y加入序列,问多次操作后能否得到数k.
假设从序列中取出四个数x,y,p,q,x和y可以组合成2x-y,p和q可以组合成2p-q,再将(2x-y)和(2p-q)进行一步组合,可以得到2*(2x-y)-(2p-q)=x+2*(x-y)+(x-p)+(q-p),对于任意的四个数都可以得到这样的组合,对于任意的数来说,都会得到ai+
∑
\sum
∑j,k(aj−ak),也就是一个任意的数和其他任意数对查的线性组合。
对于本题的就是对上面说的aj−ak求gcd,但是肯定不能求出所有的任意两数之差,我们发现只需要计算出相邻两数之差,线性组合后就相当于求出了所有,而ai也都可以被表示出来,因此我们只需要从序列中任选一个数 ai判断 ( k−ai ) % g c d 是否为零。
#pragma GCC optimize(2) #pragma G++ optimize(2) #include<bits/stdc++.h> #include<math.h> #include<iostream> #include<algorithm> #include<cstdio> #include<stack> #include<map> #include<string> #include<vector> using namespace std; #define ll long long const int maxn=2e5+9; const int mod=1e9+7; const int inf=0x3fffffff; const double PI=acos(-1); typedef unsigned long long ull; /*clever*/ inline int read(){ char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();} while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();} return x * f; } ll Eular(ll n){//欧拉函数 ll ans = n; for(int i=2; i*i <= n; ++i){ if(n%i == 0){ ans = ans/i*(i-1); while(n%i == 0) n/=i; } } if(n > 1) ans = ans/n*(n-1); return ans; } bool isPrime(ll n){//素数判定 if (n <= 3) { return n > 1; } else if (n % 2 == 0 || n % 3 == 0) { return false; } else { for (ll i = 5; i * i <= n; i += 6) { if (n % i == 0 || n % (i + 2) == 0) { return false; } } return true; } } ll qpow(ll a,ll b,ll p){ ll ans=1; a=a%p; while(b){ if(b&1) ans=1ll*ans*a%p; a=1ll*a*a%p; b>>=1; } return ans%p; } ll gcd(ll a,ll b){ if(a==0) return b; return gcd(b%a,a); } int a[maxn]; int main() { int t, n; ll k; cin >> t; while (t--) { cin >> n >> k; for (int i = 1; i <= n; i++) cin >> a[i]; sort(a + 1, a + 1 + n); ll g = 0; for (int i = 2; i <= n; i++) { g = gcd(g, a[i] - a[i - 1]); } if ((k - a[1]) % g == 0) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。