CF 1806 C Sequence Master

题意简述

令全集 \(U=\{1,2,3,\dots,2m\}\)

一个序列 \(Q\)的,当且仅当 \(\forall (S\subseteq U,s.t.\ |S|=m),\prod \limits_{i\in S}{Q_i}=\sum \limits_{j\in(\complement_US)} Q_j\)

定义两个长度为 \(k\) 的序列 \(A\)\(B\)距离\(\sum\limits_{i=1}^k{|A_i-B_i|}\)

给定长度为 \(2n\) 的序列 \(P\),请找出与 \(P\) 距离最小的序列 \(Q\),输出它们的距离。

解题思路

思考怎样一个序列满足它是好的。

显然,当 \(n=1\) 时,\((x,x),s.t.\ x\in \mathbb{Z}\) 都是可以的。因此我们只用考虑 \(n\geq2\) 的情况。

不妨先讨论 \(n=2\) 时的答案。它应当满足四元轮换对称方程组:

\[\left \{ \begin{aligned} ab=c+d\\ ac=b+d\\ ad=b+c\\ bc=a+d\\ bd=a+c\\ cd=a+b\\ \end{aligned} \right. \tag{1.1} \]

它的必要条件显然是:

\[ab=c+d,cd=a+b \tag{1.2} \]

式子 \((1.2)\) 的必要条件又是(就是把两式相加):

\[a+b+ab=c+d+cd\iff (a+1)(b+1)=(c+1)(d+1)\tag{1.3} \]

由轮换性质可得:

\[|a+1|=|b+1|=|c+1|=|d+1|\tag{1.4} \]

或:

\[\sum[a=-1]\geq3\tag{1.5} \]

式子 \((1.5)\) 就是说四个未知数中有三个都是 \(-1\),此时 \((1.3)\) 等式两边都是 \(0\)


先讨论式子 \((1.4)\)。设 \(x\),显然四个数要么是 \(x\),要么是 \(-x-2\)

若同时存在 \(-x-2\)\(x\)

  1. \(x=-1\) 时,\(a=b=c=d=-1\),带回原式,不成立。

  2. \(x\neq-1\) 时,四个数的正负不尽相同。不妨令 \(x\geq0\),那么 \(-x-2\leq-2<0\)

    1. 若有一个数为负,不妨令 \(a\) 为负,那么式子 \(ab=c+d\) 一定不成立(左负右非负)。

    2. 若有两个,不妨令 \(a,b\) 为负,那么式子 \(cd=a+b\) 一定不成立(左非负右负)。

    3. 若有三个,不妨令 \(a,b,c\) 为负,那么:

      \[ab=c+d\iff (-x-2)^2=-2 \]

      无解。

因此,仅存在 \(a=b=c=d=x\) 的情况。

可得方程:

\[x^2=2x \]

解得 \(x=0\text{ 或 }2\)。带回原方程,发现都成立。

再来看式子 \((1.5)\),发现很好解:\(x=2\)。即 \(a=2,b=c=d=-1\) 是一组解,带回原方程组,可行。


推广一下,至 \(n\geq2\)。当 \(n>2\) 时,情况只会比 \(n=2\) 时更苛刻,不会存在比 \(n=2\) 时更多的情况。

式子 \((1.4)\) 可以推广为:

\[x^n=nx\tag{2.1} \]

解得:\(x=0\)\(x=\sqrt[n-1]n\) ,在 \(n>2\) 时,\(\sqrt [n-1]{n}\) 一定不是整数,因为显然 \(1<\sqrt[n-1]{n-1}< \sqrt[n-1]n<\sqrt[n-1]{2^{n-1}}=2\)

式子 \((1.5)\) 可以推广为:

\[(-1)^{n-1}\cdot x=-n\text { 且 }x-n+1=(-1)^n\tag{2.2} \]

发现只有当 \(n\bmod 2=0\) 时,才有解,解为 \(x=n\)


综上所述,有四种情况:

  1. \(n=1\) 时,任意整数二元组即可。
  2. \(n=2\) 时,存在解 \((2,2,2,2)\)
  3. \(n\bmod2=0\) 时,存在解 \((n,-1,-1,\cdots)\),顺序可以改变。
  4. \(n\geq2\) 时,存在解 \((0,0,\cdots)\)

代码实现

//省略了头文件
#define int long long
using namespace std;

#define R myio::read_int()
//也就是说,R 代表的是读入的数。这里省略了快读。
int solve() {
	int n=R;
	int *a=new int[2*n+1];
	for(int i=1;i<=2*n;i++) a[i]=R;
	int minans=9e18;
	if(n==1) minans=abs(a[2]-a[1]);
	if(n==2) {
		int sum=0;
		for(int i=1;i<=4;i++) 
			sum+=abs(2-a[i]);
		minans=min(minans,sum);
	} if(n%2==0) {
		int sum=0;
		for(int i=1;i<=2*n;i++) sum+=abs(-1-a[i]);	//先求和
		for(int i=1;i<=2*n;i++) 
			minans=min(minans,sum-abs(-1-a[i])+abs(n-a[i]));	//再改值
	} int sum=0;
	for(int i=1;i<=2*n;i++) sum+=abs(a[i]);
	delete []a;
	return min(minans,sum);
}
signed main(){
	int t=R;
	while(t--) myio::print_int(solve());
	return 0;
}
posted @ 2023-03-19 16:25  robinyqc  阅读(42)  评论(0)    收藏  举报