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)\) 做法即可。
于是原问题获得顺利的解决。
代码。

浙公网安备 33010602011771号