赞
踩
题意: 给你 n n n 个数,和一个数 k k k ,现在有一种操作,可以将任意两个数 x , y x,y x,y ,然后将 2 x − y 2x - y 2x−y 加入(原来的 x , y x,y x,y 仍然存在)。
思路: 2 x − y 2x-y 2x−y 可以看做 x + ( x − y ) x + (x-y) x+(x−y) 即该数与两数之差的和。用几组样例模拟一下,可以发现,无论进行多少次操作,始终都是 a i + ∑ j , k ( a j − a k ) a_i + \sum_{j,k}(a_j - a_k) ai+∑j,k(aj−ak) 就是有若干组差值加上一个值。
根据裴蜀定理:对于 n n n 个整数, 若 g c d ( a 1 , a 2 , … , a n ) = d gcd(a_1,a_2, \dots,a_n)=d gcd(a1,a2,…,an)=d,那么存在整数 x 1 , x 2 , … , x n x_1,x_2,\dots,x_n x1,x2,…,xn 使得 x 1 ∗ a 1 + x 2 ∗ a 2 + ⋯ + x n ∗ a n = d x_1 * a_1 + x_2 * a_2+\dots+x_n*a_n = d x1∗a1+x2∗a2+⋯+xn∗an=d
这里因为差值组有 n 2 n^2 n2 对,只需要取 n − 1 n - 1 n−1 对,即: a 2 − a 1 , a 3 − a 2 , … , a n − a n − 1 a_2 - a_1, a_3-a_2,\dots,a_n-a_{n-1} a2−a1,a3−a2,…,an−an−1 。这样包括了所有的数。
算出这 n − 1 n-1 n−1个数的最大公约数 g g g ,然后遍历原题给的 n n n 个数,看是否存在 ( k − a i ) % g = = 0 (k-a_i)\%g==0 (k−ai)%g==0 ,若存在,那必定存在 n − 1 n-1 n−1 个整数 满足裴蜀定理,也就满足了题目要求。
代码:
#include<iostream> #include<cstdio> #include<vector> #include<queue> #include<stack> #include<cmath> #include<map> #include<cstring> #include<string> #include<algorithm> #include<iomanip> #define fi first #define se second //#include<stdlib.h> //#include <time.h> //srand((unsigned)time(NULL)); using namespace std; typedef long long ll; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; using namespace std; const double eps = 1e-7; const int N = 1e6 + 10; int n; int main() { int t; scanf("%d", &t); while (t--) { ll n, k; scanf("%lld%lld", &n, &k); vector<ll> a(n + 1, 0); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } ll g = a[2] - a[1]; for (int i = 3; i <= n; i++) { g = __gcd(g, a[i] - a[i - 1]); } bool f = false; for (int i = 1; i <= n; i++) { if ((k - a[i]) % g == 0) f = true; } if (f) printf("YES\n"); else printf("NO\n"); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。