C. Sequence Master

C. Sequence Master

For some positive integer m, YunQian considers an array q of 2m (possibly negative) integers good, if and only if for every possible subsequence of q that has length m, the product of the m elements in the subsequence is equal to the sum of the m elements that are not in the subsequence. Formally, let U={1,2,,2m}. For all sets SU such that |S|=m, iSqi=iUSqi.

Define the distance between two arrays a and b both of length k to be i=1k|aibi|.

You are given a positive integer n and an array p of 2n integers.

Find the minimum distance between p and q over all good arrays q of length 2n. It can be shown for all positive integers n, at least one good array exists. Note that you are not required to construct the array q that achieves this minimum distance.

Input

The first line contains a single integer t (1t104) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer n (1n2105).

The second line of each test case contains 2n integers p1,p2,,p2n (|pi|109).

It is guaranteed that the sum of n over all test cases does not exceed 2105.

Output

For each test case, output the minimum distance between p and a good q.

Example

input

复制代码
4
1
6 9
2
1 2 2 1
2
-2 -2 2 2
4
-3 -2 -1 0 1 2 3 4
复制代码

output

3
2
5
13

Note

In the first test case, it is optimal to let q=[6,6].

In the second test case, it is optimal to let q=[2,2,2,2].

 

解题思路

  首先直觉上就会觉得满足条件的q数量会很少,同时可以发现q=[ 0,0,,02n ]一定是满足条件的,因此对于nZ,总是存在一个q,即一定有解。我们接下来再考虑是否存在其他满足条件的q

  先考虑q中所有元素都相同的情况。

  很明显当n=1的情况,必然会有q1=q2,可以等于任意值。

  当n=2,假设每个元素都为x,那么必然会有xn=nx  x=nn1=2。同时根据该等式,很明显当n>2时等式不存在正整数解。

  因此只有当n=1n=2,才存在除了全0以外所有元素都相同的q

  接下来考虑q中所有元素不都相同的情况,先考虑n为偶数的情况

  由于此时q中至少存在两个元素不同,不妨假设q1q2。满足等式{q1q3q4qn+1=q2+qn+2+qn+3++q2n       (1)q2q3q4qn+1=q1+qn+2+qn+3++q2n       (2)

  (1)(2)得到(q1q2)q3q4qn+1=q2q1  (q1q2)(q3q4qn+1+1)=0

  由于q1q2,因此必然有q3q4qn+1+1=0,即q3q4qn+1=1。由于qiZ,有奇数个qi连乘,故只能有qi=1

  同理我们考虑其他类似的约束条件,即U={3,4,,2n},对于U所有满足|S|=n1的子集SU,有{q1iSqi=q1+iUSqiq2iSqi=q2+iUSqi

  就可以发现q3=q4==q2n=1,把结果代入(1)式,就会得到q1+q2=n1。同时又因为q1q2qn=qn+1+q2n,因此有q1q2=n。这样就可以解得{q1,q2}={1,n}

  即对于n为偶数的情况,我们可以构造出q=[ 1,1,,12n1, n ]

  那么对于n为奇数的情况呢?与上面的推导过程一样,最后得到q3q4qn+1=1,由于qiZ,此时有偶数个qi连乘,很明显此时没有解。

  故只有当2n,有q=[ 1,1,,12n1, n ]

  接下来我们只需要针对n来分类讨论取最小值就可以了:

  1. 先考虑q中元素均为0的情况,此时最小值为ans=i=12n|pi|
  2. 如果n=1,为了得到最小值构造q=[p1,p1]q=[p2,p2],那么就有ans=min{ans, |p1p2|}
  3. 如果n=2,构造q=[2,2,2,2],那么就有ans=min{ans, i=14|pi2|}
  4. 最后如果2n,构造q=[ 1,1,,12n1, n ]。对p从小到大排序,那么就有ans=min{ans, i=12n|piqi|}

  关于上面的第4步,如果有序列pq,定义两个序列的距离为i=1n|piqi|。如果可以任意排列两个序列的元素,那么当pq均满足非递减顺序时,即p1p2pnq1q2qn,此时距离能够取到最小值,证明见附录部分。

  AC代码如下,时间复杂度为O(nlogn)

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

  其中对于第4步,由于q中只有一个元素是n,其余的元素都是1,因此我们可以枚举p中哪个元素与n求差。定义s=i=12n|pi+1|,那么如果pkn作差,就有i=1n|piqi|=s|pk+1|+|pkn|

  AC代码如下,时间复杂度为O(n)

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

 

附录

  有序列pq,定义两个序列的距离为i=1n|piqi|,序中的元素可以任意重新排序。证明当满足p1p2pnq1q2qn时,两个序列的距离取到最小值。

  不妨固定p,使得p1p2pn。同时q不满足q1q2qn,因此至少存在一对qiqj,满足qiqji<j

  如果qi=qj,仅考虑i, j两个位置对距离的贡献,那么很明显不管是否交换pipji, j两个位置对距离的贡献都相同,因此我们只考虑qi>qj,且pi<pj的情况。

  接下来证明通过交换qiqj,能够使得i, j两个位置对距离的贡献减少。为此我们假设pi=a, pj=b, qi=d, qj=c,同时有a<b, c<d

  分情况讨论:

  1. bc,即a<bc<d

  交换cd前,距离为|ad|+|bc|=da+cb,交换cd后,有d<c,距离就变成|ac|+|bd|=ca+db,用交换前减去交换后得到da+cb(ca+db)=0,即交换后的距离不变。

  2. ac<b

  2.1. bd,即ac<bd

  交换cd前,距离为|ad|+|bc|=da+bc,交换cd后,有d<c,距离就变成|ac|+|bd|=ca+db,用交换前减去交换后得到da+bc(ca+db)=2(bc)>0,即交换后的距离变小。

  2.2. b>d,即ac<d<b

  交换cd前,距离为|ad|+|bc|=da+bc,交换cd后,有d<c,距离就变成|ac|+|bd|=ca+bd,用交换前减去交换后得到da+bc(ca+bd)=2(dc)>0,即交换后的距离变小。

  3. c<a

  3.1. bd,即c<a<bd

  交换cd前,距离为|ad|+|bc|=da+bc,交换cd后,有d<c,距离就变成|ac|+|bd|=ac+db,用交换前减去交换后得到da+bc(ac+db)=2(ba)>0,即交换后的距离变小。

  3.2. ad<b,即c<ad<b

  交换cd前,距离为|ad|+|bc|=da+bc,交换cd后,有d<c,距离就变成|ac|+|bd|=ac+bd,用交换前减去交换后得到da+bc(ac+bd)=2(da)0,即交换后的距离变小。

  3.3. d<a,即c<d<a<b

  交换cd前,距离为|ad|+|bc|=ad+bc,交换cd后,有d<c,距离就变成|ac|+|bd|=ac+bd,用交换前减去交换后得到ad+bc(ac+bd)=0,即交换后的距离不变。

  综上所述,如果序列p满足p1p2pn,对于序列q如果存在qiqj满足qi>qji<j,那么交换qiqj能使得距离变小。为了使得距离最小,最终q一定满足q1q2qn

  定理得证。

  同时可以推导得到当序列pq满足p1p2pnq1q2qn时,两个序列的距离取到最大值。

 

参考资料

  Codeforces Round #858 (Div. 2) Editorial:https://codeforces.com/blog/entry/114048

posted @   onlyblues  阅读(207)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示