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"; } ```

No comments:

Post a Comment

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...