You are given an array a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an consisting of integers such that a 1 + a 2 + … + a n = 0 a_1 + a_2 + \ldots + a_n = 0 a1+a2+…+an=0.
You have to rearrange the elements of the array a a a so that the following condition is satisfied:
KaTeX parse error: Expected 'EOF', got '&' at position 79: …s + a_r \rvert &̲lt; \max(a_1, a…
where
∣
x
∣
|x|
∣x∣ denotes the absolute value of
x
x
x.
More formally, determine if there exists a permutation p 1 , p 2 , … , p n p_1, p_2, \ldots, p_n p1,p2,…,pn that for the array a p 1 , a p 2 , … , a p n a_{p_1}, a_{p_2}, \ldots, a_{p_n} ap1,ap2,…,apn, the condition above is satisfied, and find the corresponding array.
Recall that the array
p
1
,
p
2
,
…
,
p
n
p_1, p_2, \ldots, p_n
p1,p2,…,pn is called a permutation if for each integer
x
x
x from
1
1
1 to
n
n
n there is exactly one
i
i
i from
1
1
1 to
n
n
n such that
p
i
=
x
p_i = x
pi=x.
给你一个由整数组成的数组
a
1
,
a
2
,
…
,
a
n
a_1, a_2, \ldots, a_n
a1,a2,…,an ,其中
a
1
+
a
2
+
…
+
a
n
=
0
a_1 + a_2 + \ldots + a_n = 0
a1+a2+…+an=0 .
你必须重新排列数组 a a a 中的元素,以满足下列条件:
KaTeX parse error: Expected 'EOF', got '&' at position 79: …s + a_r \rvert &̲lt; \max(a_1, a…
其中
∣
x
∣
|x|
∣x∣ 表示
x
x
x 的绝对值。
更正式地说,确定是否存在一种排列 p 1 , p 2 , … , p n p_1, p_2, \ldots, p_n p1,p2,…,pn ,使得数组 a p 1 , a p 2 , … , a p n a_{p_1}, a_{p_2}, \ldots, a_{p_n} ap1,ap2,…,apn 满足上述条件,并找出相应的数组。
回顾数组
p
1
,
p
2
,
…
,
p
n
p_1, p_2, \ldots, p_n
p1,p2,…,pn ,如果从
1
1
1 到
n
n
n 的每个整数
x
x
x 中,从
1
1
1 到
n
n
n 恰好有一个
i
i
i 令
p
i
=
x
p_i = x
pi=x 满足条件,那么这个数组
p
1
,
p
2
,
…
,
p
n
p_1, p_2, \ldots, p_n
p1,p2,…,pn 就叫做一个排列。
Input
Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 50 000 1 \le t \le 50\,000 1≤t≤50000). The description of the test cases follows.
The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 300 000 1 \le n \le 300\,000 1≤n≤300000) — the length of the array a a a.
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an ( − 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \le a_i \le 10^9 −109≤ai≤109) — elements of the array a a a. It is guaranteed that the sum of the array a a a is zero, in other words: a 1 + a 2 + … + a n = 0 a_1 + a_2 + \ldots + a_n = 0 a1+a2+…+an=0.
It is guaranteed that the sum of
n
n
n over all test cases does not exceed
300
000
300\,000
300000.
输入
每个测试包含多个测试用例。第一行包含测试用例的数量 t t t ( 1 ≤ t ≤ 50 000 1 \le t \le 50\,000 1≤t≤50000 )。测试用例说明如下。
每个测试用例的第一行都包含一个整数 n n n ( 1 ≤ n ≤ 300 000 1 \le n \le 300\,000 1≤n≤300000 ) - 数组的长度 a a a 。
每个测试用例的第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an ( − 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \le a_i \le 10^9 −109≤ai≤109 ) - 数组 a a a 的元素。可以保证数组 a a a 的总和为零,换句话说,也就是 a 1 + a 2 + … + a n = 0 a_1 + a_2 + \ldots + a_n = 0 a1+a2+…+an=0 的总和为零: a 1 + a 2 + … + a n = 0 a_1 + a_2 + \ldots + a_n = 0 a1+a2+…+an=0 .
保证所有测试用例中
n
n
n 的总和不超过
300
000
300\,000
300000 。
思路:
没有任何思路,使用maxx和minn记录前缀最大值和最小值,贪心的去选择即可
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define endl '\n'
#define int long long
using namespace std;
const int N = 1e6 + 10, INF = 1e17;
int a[N];
int all;
int maxx = -INF;
int minn = INF;
vector<int>fu, vi;
vector<int>ans;
int n;
int sum;
bool check(int x)
{
int now = sum + x;
if (abs(now - maxx) < all && abs(now - minn) < all)return true;
return false;
}
bool check2()
{
for (int i = 0;i < n;i++)
{
for (int j = i;j < n;j++)
{
int t = 0;
for (int k = i;k <= j;k++)
{
t += ans[k];
}
// look(t);
if (t >= all)
{
bug;
cout << i << ' ' << j << endl;
}
}
}
}
void solve()
{
fu.clear();
vi.clear();
ans.clear();
cin >> n;
maxx = -INF;
minn = INF;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] < 0) fu.push_back(a[i]);
else vi.push_back(a[i]);
maxx = max(maxx, a[i]);
minn = min(minn, a[i]);
}
all = maxx - minn;
sort(vi.begin(), vi.end(), greater<int>());
sort(fu.begin(), fu.end(), greater<int>());
maxx = 0;
minn = 0;
sum = 0;
for (int i = 1;i <= n;i++)
{
int tmp;
if (vi.size() == 0)
{
tmp = fu.back();
fu.pop_back();
}
else if (fu.size() == 0)
{
tmp = vi.back();
vi.pop_back();
}
else if (check(vi.back()) && check(fu.back()))
{
if (vi.size() > fu.size())
{
tmp = vi.back();
vi.pop_back();
}
else
{
tmp = fu.back();
fu.pop_back();
}
}
else if (check(vi.back()))
{
tmp = vi.back();
vi.pop_back();
}
else if (check(fu.back()))
{
tmp = fu.back();
fu.pop_back();
}
else
{
cout << "No" << endl;
return;
}
if (!check(tmp))
{
cout << "No" << endl;
return;
}
ans.push_back(tmp);
sum += tmp;
maxx = max(maxx, sum);
minn = min(minn, sum);
}
cout << "Yes" << endl;
for (auto it : ans)
{
cout << it << ' ';
}
cout << endl;
// check2();
return;
}
signed main()
{
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}