D. Imbalanced Arrays

发布时间 2023-09-01 17:38:18作者: onlyblues

D. Imbalanced Arrays

Ntarsis has come up with an array $a$ of $n$ non-negative integers.

Call an array $b$ of $n$ integers imbalanced if it satisfies the following:

  • $-n\le b_i\le n$, $b_i \ne 0$,
  • there are no two indices $(i, j)$ ($1 \le i, j \le n$) such that $b_i + b_j = 0$,
  • for each $1 \leq i \leq n$, there are exactly $a_i$ indices $j$ ($1 \le j \le n$) such that $b_i+b_j>0$, where $i$ and $j$ are not necessarily distinct.

Given the array $a$, Ntarsis wants you to construct some imbalanced array. Help him solve this task, or determine it is impossible.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^5$). The description of the test cases follows.

The first line of each test case has a single integer $n$ ($1 \leq n \leq 10^5$).

The next line contains $n$ integers $a_1, a_2, \ldots, a_n$ ($0 \leq a_i \leq n$).

It is guaranteed that the sum of $n$ across all test cases does not exceed $10^5$.

Output

For each test case, output "NO" if there exists no imbalanced array.

Otherwise, output "YES". Then, on the next line, output $n$ integers $b_1, b_2, \ldots, b_n$ where $b_i \neq 0$ for all $1 \leq i \leq n$ — an imbalanced array.

Example

input

5
1
1
4
1 4 3 4
3
0 1 0
4
4 3 2 1
3
1 3 1

output

YES
1 
NO
YES
-3 1 -2 
YES
4 2 -1 -3 
YES
-1 3 -1

Note

For the first test case, $b = [1]$ is an imbalanced array. This is because for $i = 1$, there is exactly one $j$ ($j = 1$) where $b_1 + b_j > 0$.

For the second test case, it can be shown that there exists no imbalanced array.

For the third test case, $a = [0, 1, 0]$. The array $b = [-3, 1, -2]$ is an imbalanced array.

  • For $i = 1$ and $i = 3$, there exists no index $j$ such that $b_i + b_j > 0$.
  • For $i = 2$, there is only one index $j = 2$ such that $b_i + b_j > 0$ ($b_2 + b_2 = 1 + 1 = 2$).

Another possible output for the third test case could be $b = [-2, 1, -3]$.

 

解题思路

  首先从前两个条件可以知道我们只能从每一对$(1, -1), \, (2, -2), \, (n, -n)$中选择一个数,比如选了$1$就不能再选$-1$,但$1$可以重复选。

  如果存在合法的数组$b$,那么$b$一定存在一个绝对值最大的数,假设为$b_i$。如果$b_i < 0$,那么一定有$a_i = 0$;否则如果$b_i > 0$,那么一定有$a_i = n$。同时$a$中不可能同时存在$a_i = 0$和$a_j = n$,否则就会推出$b_i + b_j < 0$和$b_j + b_i > 0$,就与第二个条件矛盾了。

  因此只要$a$中存在$a_i = 0$或者$a_i = n$(不能同时存在),那么就在最大的数对中(即$(n, -n)$)取相应的元素赋值给$b_i$,然后再把$a_i$去掉,继续处理剩余的元素。

  为此可以先对$a$按照值的大小进行排序,然后设置两个指针$l$和$r$分别表示$a$的最左端和最右端,然后判断是否满足上面所说的条件即可。其中如果去掉的最右端的$a_r$,由于$b_r > 0$,因此$a$中剩余的元素都要减去$1$,而删除$a_l$并不需要改变剩余元素的值。因此判断是否满足的条件就是$\Big(a_l - (n-r) = 0\Big) \, \oplus \, \Big( a_r - (n-r) =r-l+1 \Big)$的值是否为$1$,其中$n-r$就是去掉右端的元素数量。

  AC代码如下,时间复杂度为$O(n \log{n})$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 1e5 + 10;
 7 
 8 int a[N], p[N];
 9 int ans[N];
10 
11 void solve() {
12     int n;
13     scanf("%d", &n);
14     for (int i = 1; i <= n; i++) {
15         scanf("%d", a + i);
16         p[i] = i;
17     }
18     sort(p + 1, p + n + 1, [&](int i, int j) {
19         return a[i] < a[j];
20     });
21     for (int i = 1, j = n, k = n; i <= j; k--) {
22         if (!(a[p[i]] - (n - j)) ^ (a[p[j]] - (n - j) == j - i + 1)) {
23             if (!(a[p[i]] - (n - j))) ans[p[i++]] = -k;
24             else ans[p[j--]] = k;
25         }
26         else {
27             printf("NO\n");
28             return;
29         }
30     }
31     printf("YES\n");
32     for (int i = 1; i <= n; i++) {
33         printf("%d ", ans[i]);
34     }
35     printf("\n");
36 }
37 
38 int main() {
39     int t;
40     scanf("%d", &t);
41     while (t--) {
42         solve();
43     }
44     
45     return 0;
46 }

 

参考资料

  Codeforces Round 887 (Div 1, Div 2) Tutorial:https://codeforces.com/blog/entry/116940