《Nezzar and Symmetric Array》
题意注意的是,相反数必定在数组中。
首先很容易可以算出每对相反数的总差值和是一样的,所以d中的差值一定要成对出现。
且,可以发现,对于差值的计算有两种情况。
对于y,计算和-x , x的差值。
当y < x。dis = (x - y) + (y + x) = 2 * x;
当y > x。dis = (y - x) + (y + x) = 2 * y;
所以dis的总和最终必定是2的倍数,也就是说d中的值必须是偶数。
有了上面这个计算的差值,那么我们可以发现最大的数mx,它的差值和就是2 * mx * n。
第二大的数sec就是2 * (n - 1) * sec + 2 * mx,以此类推,我们就可以计算出所有原来的数。
1:在计算过程中,如果满足无法整除就说明求不出这个数,那么显然不满足。
2:因为题目中开始说明过了原数组中的数是全部不相同的,所以我们要需要判断一下求出来的数有没有重复。
3:我们上面都当x,y是正整数,所以我们求出来的数也要是正的才满足我们的递推。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 3e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; LL d[N << 1]; int main() { int ca;ca = read(); while(ca--){ int n;n = read(); map<LL,int> mp; for(int i = 1;i <= 2 * n;++i) d[i] = read(),mp[d[i]]++; sort(d + 1,d + 2 * n + 1); int f = 0; for(int i = 1;i <= 2 * n;++i){ if(mp[d[i]] % 2 != 0 || d[i] % 2 != 0) f = 1; } LL ma = d[2 * n],sum = 0; if(d[2 * n] % (2 * n) != 0) f = 1; ma /= (2 * n); map<LL,int> have; have[ma]++; for(int i = 2 * n - 2;i >= 1;i -= 2){ sum += 2 * ma; if((d[i] - sum) % i != 0) f = 1; ma = (d[i] - sum) / i; if(have[ma] == 1) f = 1; have[ma]++; if(ma <= 0) f = 1; } printf("%s\n",f ? "NO" : "YES"); } system("pause"); return 0; }