Monday, 5 July 2021
Nezzar and Symmetric Array
This is an unofficial editorial for [Nezzar and Symmetric Array](https://codeforces.com/problemset/problem/1478/C).
## Problem Statement
Long time ago there was a symmetric array $a_1$, $a_2$, ... ,$a_{2n}$ consisting of $2n$ distinct integers. Array $a_1$, $a_2$, ... ,$a_{2n}$ is called symmetric if for each integer $1 <= i <= 2n$, there exists an integer $1 <= j <= 2n$ such that $a_i = -a_j$.
For each integer $1<=i<=2n$, Nezzar wrote down an integer $d_i$ equal to the sum of absolute differences from $a_i$ to all integers in $a$, i. e. $d_i$ = $\sum_{j=1}^{2n} |a_i - a_j|$.
Now a million years has passed and Nezzar can barely remember the array $d$ and totally forget $a$. Nezzar wonders if there exists any symmetric array 𝑎 consisting of $2n$ distinct integers that generates the array $d$.
## Input
The first line contains a single integer $t$ ($1 <= t <= 10^5$) — the number of test cases.
The first line of each test case contains a single integer 𝑛 ($1 <= n <= 10^5$).
The second line of each test case contains $2n$ integers $d_1, d_2, ..., d_{2n}$ ($1 <= d_i <= 10^{12}$).
It is guaranteed that the sum of 𝑛 over all test cases does not exceed $10^5$.
## Output
For each test case, print "YES" in a single line if there exists a possible array 𝑎. Otherwise, print "NO".
You can print letters in any case (upper or lower).
## Approach
Here's the simulation of the first example.
```
a = [1 -3 -1 3]
i = 0 : 0 + 4 + 2 + 2 = 8
i = 1 : 4 + 0 + 2 + 6 = 12
i = 2 : 2 + 2 + 0 + 4 = 8
i = 3 : 2 + 6 + 4 + 0 = 12
d = [8, 12, 8, 12]
```
Each element has a positive and negative value. Supposing the positive value is $ x $, and the absolute difference to $(y, -y)$ would be $| x - y | + | x + y | $. Similarly, for $ -x $, that would be $ |-x - y | + |-x + y |$, which is also $|x - y| + |x + y|$. Therefore, for each $ d[i] $, there would be a pair as well.
For $|x - y| + |x + y|$, we have two different cases. For $x > y$, $|x - y| + |x + y|$ would be $ 2 * x $. For $x > y$, $|x - y| + |x + y|$ would be $ 2 * y $. Now we know that $|x - y| + |x + y|$ = $2 * max(x, y)$.
For each $ d[i] $, it is the sum of each absolute differences from $a[i]$ to all integers. Combined with the previous finding, we got
$$
d[i] = \sum_{j=1}^{2n} max(abs(a[i]), abs(a[j]))
$$
Given the array $d$, how can we generate the array $a$ back? Supposing the maximum element in $a$ is called $max_1$, the corresponding $d[i]$ would be $max_1 * 2 * n$. Therefore, we now have $max_1 = d[i] / 2 / n$. For the second maximum element, let's say $max_2$, as there is only $max_1$ which is greater than $max_2$, all other $(n - 1)$ elements are less than or equal to $max2$. The sum of absolute differences to them would be $max_2 * 2 * (n - 1)$. As $max_2 < max_1$, we need to add $max_1 * 2$ back to $d[i]$.
Similarly, we can do the same thing one by one to get the original array $a$ back. We can induce that
$$
max_1 = d[i] / 2 / n
$$
$$
max_2 = (d[i] - max_1 * 2) / 2 / (n - 1)
$$
$$
max_3 = (d[i] - max_2 * 2) / 2 / (n - 2)
$$
$$
max_4 = (d[i] - max_3 * 2) / 2 / (n - 3)
$$
$$
\vdots
$$
$$
max_m = (d[i] - max_{m - 1} * 2) / 2 / (n - k)
$$
For each elelment $x$, we need to check the occurence of its absolute value. If $x$ is odd or its occurence is odd, then the answer is $NO$. Also, if $x$ appears more than 2 times, that would be also $NO$. For each $max_m$, we can verify that if we can retrieve an integer, i.e. $(d[i] - max_{m - 1} * 2) / 2 % (n - k) $ is $0$ or not. If not, that is also $NO$. if $(d[i] - max_{m - 1} * 2) / 2 / (n - k) $ appears before or it is less than or equal to $0$, that is also not a correct answer. Therefore, we have 6 cases to check in total. For other cases, that would be $YES$.
## Solution
```
void solve() {
long long n; cin >> n;
map<long long, long long> vis, m;
for(int i = 0; i < 2 * n; i++) cin >> d[i], m[-d[i]]++;
long long cur_sum = 0, k = 0;
EACH(it, m) {
long long abs_difference = -it.fi, occurrence = it.se;
if(abs_difference % 2 || occurrence % 2 || occurrence > 2) {
cout << "NO" << "\n";
return;
}
long long p = (abs_difference - cur_sum * 2) / 2;
long long q = n - k;
if(p % q) {
cout << "NO" << "\n";
return;
}
p /= q;
if(vis.count(p) || p <= 0) {
cout << "NO" << "\n";
return;
}
vis[p] = 1, cur_sum += p, k++;
}
cout << "YES" << "\n";
}
```
Subscribe to:
Post Comments (Atom)
A Fun Problem - Math
# Problem Statement JATC's math teacher always gives the class some interesting math problems so that they don't get bored. Today t...
-
SHA stands for Secure Hashing Algorithm and 2 is just a version number. SHA-2 revises the construction and the big-length of the signature f...
-
Contest Link: [https://www.e-olymp.com/en/contests/19775](https://www.e-olymp.com/en/contests/19775) Full Solution: [https://github.com/...
No comments:
Post a Comment