CF2103E 题解

CF2103E 题解

回到洛谷题解

不难注意到题目所述操作的本质是:对一对满足 \(a_i+a_j=k\)\((a_i,a_j)\),在和不变,且分配后仍然有 \(0\le a_i,a_j \le k\) 的情况下重新进行分配。

比如 \(a_i=2,a_j=7,k=9\) 时,一次操作可以让 \((a_i,a_j)\) 变为 \((0,9)\)\((1,8)\)\((2,7)\)\((3,6)\) 等等。

分析题目条件。发现操作次数不多于 \(3n\) 且要让数组单调不降。考虑进行 \(n\) 次在 \(3\) 步之内交换数组中的两个数,使得原数组从小到大排序。

假设要交换 \(a_x\)\(a_y\)。当 \(a_x+a_y=k\) 时,操作是简单的。

考虑 \(a_x+a_y\neq k\) 的情况。发现我们必须借助另外一组 \(a_i+a_j=k\) 来交换 \(a_x\)\(a_y\)

如何借助呢?回顾交换的本质,我们要需要先把 \(a_x\) 放到一个临时变量里。对应到这题,我们需要把 \(a_i\)\(a_j\) 中的一个换成 \(a_x\)。之后的操作就变得显然了。

\(px=a_x\)\(py=a_y\)\(pi=a_i\)\(pj=p_j\)。我们可以按如下方式交换:

操作次数 此时 \(a_x\) 此时 \(a_y\) 此时 \(a_i\) 此时 \(a_j\) 操作的 \((i,j,k)\)
初始 \(px\) \(py\) \(pi\) \(pj\)
第一次操作 \(px\) \(py\) \(px\) \(k-px\) \((i,j,pi-px)\)
第二次操作 \(py\) \(py\) \(px\) \(k-py\) \((x,j,px-py)\)
第三次操作 \(py\) \(px\) \(px\) \(k-px\) \((y,j,py-px)\)

发现此时 \(a_i+a_j=k\) 依然成立,因此我们可以多次借助 \(a_i\)\(a_j\) 进行操作。

但是有一个问题:在我们对其它数排完之后,剩下的 \(a_i\)\(a_j\) 还没有排序到位。而我们的操作次数已经快要用完了。

怎么办呢?如果这两个数再操作一步就可以使得整个序列有序就好了。于是我们考虑\(a_1\)\(a_n\) 相加等于 \(k\)。这样只需一次操作使得 \(a_1=0,a_n=k\) 就可以了。

跟交换数一样,我们考虑借助一组 \(a_i+a_j=k\) 来让 \(a_1\)\(a_n\) 相加等于 \(k\)​。这个比较显然,这里直接给出方案(令 \(pa = a_1,pb=a_n\)):

操作次数 此时 \(a_1\) 此时 \(a_n\) 此时 \(a_i\) 此时 \(a_j\) 操作的 \((i,j,k)\)
初始 \(pa\) \(pb\) \(pi\) \(pj\)
第一次操作 \(pa\) \(pb\) \(pb\) \(k-pb\) \((i,j,pi-pb)\)
第二次操作 \(pa\) \(k-pa\) \(pb\) \(pa\) \((n,j,pa+pb-k)\)

所以,我们先进行上表所述操作。接着对 \(2\)\(n-1\) 利用交换进行排序,最后通过操作让 \(a_1=0,a_n=k\)(这个很显然了,具体怎么操作留给各位思考)即可。

问题来了:给定一个数组,每次可以交换任意两个数,如何通过不超过 \(n\) 次交换进行排序呢?这是个很经典的问题,参考 CF489A\(O(n)\) 做法即可。

于是原问题获得顺利的解决。

代码

posted @ 2025-05-04 20:20  邻补角-SSA  阅读(37)  评论(0)    收藏  举报