C. Nezzar and Symmetric Array
题意:
给定一个n,输入一个长度为2n的数组d,d满足 d i = ∑ j = 1 2 n ∣ a i − a j ∣ di=\sum_{j=1}^{2n}\mid ai-aj\mid di=∑j=12n∣ai−aj∣,且a数组满足对于任意的$ai $ 1 < = i < = 2 × n 1<=i<=2\times n 1<=i<=2×n都存在一个j 1 < = j < = 2 × n 1<=j<=2\times n 1<=j<=2×n 使得 a i = − a j ai=-aj ai=−aj.现在问你是否存在这么一个a数组。
题解:
假设一定存在a数组,那么对a和d数组从小到大排序,观察一下相对关系。
假设当前这个数为a,那么任意一个比a小的数b,对a变成d数组的贡献都是2a, 因为
∣
a
+
b
∣
=
a
+
b
\mid a+b\mid=a+b
∣a+b∣=a+b且
∣
a
−
b
∣
=
a
−
b
\mid a -b\mid = a-b
∣a−b∣=a−b 他俩的和就把b给消掉了。
任意一个比a大的数c对a变成d数组的贡献都是2c因为
∣
a
−
c
∣
=
c
−
a
\mid a-c\mid=c-a
∣a−c∣=c−a,
∣
a
+
c
∣
=
a
+
c
\mid a+c\mid=a+c
∣a+c∣=a+c 他俩就把a 消掉了,也可以根据画图,相当于曼哈顿距离来理解。
因为ai和-ai对应的d是一样的所以现在我们对d数组进行排序去重,从后往前每个d / 2 再减去前面比他大的数的贡献temp再除以当前有几个数,就可以把对应的a求出来了,当然要特判一下不成立的情况。
当前这个数是奇数不成立,当前这个数出现过奇数次不成立,当前这个数操作完小于等于零也不成立,去重以后不等于原数组的一般也不成立。
Code
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <cmath>
#include <stack>
#include <iomanip>
#include <deque>
#include <sstream>
#define x first
#define y second
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 2e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
LL a[N];
int main() {
ios::sync_with_stdio(false), cin.tie(0);
int T;
cin >> T;
while (T -- ) {
cin >> n;
int x = n;
bool ok = true;
map<LL, int> mp;
for (int i = 1; i <= n * 2; i ++ ) {
cin >> a[i];
mp[a[i]] ++;
}
sort(a + 1, a + 2 * n + 1);
n = unique(a + 1, a + 2 * n + 1) - a - 1;
if (n != x) {
cout << "NO" << endl;
continue;
}
LL temp = 0;
for (int i = n; i; i -- ) {
if (a[i] & 1 || (a[i] / 2 - temp) % i || (a[i] / 2 - temp) <= 0 || mp[a[i]] & 1) {
ok = false;
break;
}
else temp += (a[i] / 2 - temp) / i;
}
if (ok) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}