C. Sequence Master
C. Sequence Master
For some positive integer , YunQian considers an array of (possibly negative) integers good, if and only if for every possible subsequence of that has length , the product of the elements in the subsequence is equal to the sum of the elements that are not in the subsequence. Formally, let . For all sets such that , .
Define the distance between two arrays and both of length to be .
You are given a positive integer and an array of integers.
Find the minimum distance between and over all good arrays of length . It can be shown for all positive integers , at least one good array exists. Note that you are not required to construct the array that achieves this minimum distance.
Input
The first line contains a single integer () — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer ().
The second line of each test case contains integers ().
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case, output the minimum distance between and a good .
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 .
In the second test case, it is optimal to let .
解题思路
首先直觉上就会觉得满足条件的数量会很少,同时可以发现一定是满足条件的,因此对于,总是存在一个,即一定有解。我们接下来再考虑是否存在其他满足条件的。
先考虑中所有元素都相同的情况。
很明显当的情况,必然会有,可以等于任意值。
当,假设每个元素都为,那么必然会有。同时根据该等式,很明显当时等式不存在正整数解。
因此只有当或,才存在除了全以外所有元素都相同的。
接下来考虑中所有元素不都相同的情况,先考虑为偶数的情况。
由于此时中至少存在两个元素不同,不妨假设。满足等式
得到
由于,因此必然有,即。由于,有奇数个连乘,故只能有。
同理我们考虑其他类似的约束条件,即,对于所有满足的子集,有
就可以发现,把结果代入式,就会得到。同时又因为,因此有。这样就可以解得。
即对于为偶数的情况,我们可以构造出。
那么对于为奇数的情况呢?与上面的推导过程一样,最后得到,由于,此时有偶数个连乘,很明显此时没有解。
故只有当,有。
接下来我们只需要针对来分类讨论取最小值就可以了:
- 先考虑中元素均为的情况,此时最小值为。
- 如果,为了得到最小值构造或,那么就有。
- 如果,构造,那么就有。
- 最后如果,构造。对从小到大排序,那么就有。
关于上面的第步,如果有序列和,定义两个序列的距离为。如果可以任意排列两个序列的元素,那么当和均满足非递减顺序时,即,,此时距离能够取到最小值,证明见附录部分。
AC代码如下,时间复杂度为:
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 }
其中对于第步,由于中只有一个元素是,其余的元素都是,因此我们可以枚举中哪个元素与求差。定义,那么如果与作差,就有。
AC代码如下,时间复杂度为:
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 }
附录
有序列和,定义两个序列的距离为,序中的元素可以任意重新排序。证明当满足,时,两个序列的距离取到最小值。
不妨固定,使得。同时不满足,因此至少存在一对和,满足且。
如果,仅考虑两个位置对距离的贡献,那么很明显不管是否交换和,两个位置对距离的贡献都相同,因此我们只考虑,且的情况。
接下来证明通过交换和,能够使得两个位置对距离的贡献减少。为此我们假设,同时有。
分情况讨论:
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离不变。
:
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离变小。
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离变小。
:
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离变小。
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离变小。
,即:
交换和前,距离为,交换和后,有,距离就变成,用交换前减去交换后得到,即交换后的距离不变。
综上所述,如果序列满足,对于序列如果存在和满足且,那么交换和能使得距离变小。为了使得距离最小,最终一定满足。
定理得证。
同时可以推导得到当序列和满足,时,两个序列的距离取到最大值。
参考资料
Codeforces Round #858 (Div. 2) Editorial:https://codeforces.com/blog/entry/114048
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17233791.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效