CF 1019 Div.2 解题报告

CF 1019 Div.2 解题报告

A

首先,对于任意若干个数 \(\{a_n\}\),一定可以构造出 \(\{b_n\}\),使得 \(\forall_{i \in [1,n]} a_i*b_i=a_1*b_1\)

那么题意转化为 \(a\) 中本质不同元素个数。

submission

B

题意:给定一个只由 \(01\) 构成的且长为 \(n\) 的字符串 \(t\)\(s='0'+t\)

现在你可以翻转(指左右翻转)\(s\) 的一个子串,请最小化 \(s\) 中满足 \(s_i \neq s_{i+1}(i \in [2,n+1])\) 的下标 \(i\) 的个数。

简单思考后分类讨论:

  • 若这样的下标个数为 \(2\),那么我们肯定可以通过翻转使下标个数减一;

  • 若这样的小标个数大于等于 \(3\),那么我们肯定可以通过翻转使下标数减二;

submission

C

题意:给定一个数组 \(a\),定义 \(med(l,r)\) 表示 \(a_l,a_{l+1},\cdots,a_r\) 的中位数(定义为第 \(\lceil \frac{r-l+1}{2} \rceil\) 小的数)。

问是否存在 \(l,r(1 \le l < r <n)\) 满足 \(med(med(1,l),med(l+1,r),med(r+1,n)) \le k\)

一个经典 Trick:判断中位数是否为一个数,那么就将大于它的数设为 \(1\),小于等于它的数为 \(-1\),求和后若和为正,那么中位数小于等于这个数。

转化后题意为:能否将 \(a\) 划分为三个非空子串,使得至少两个子串内的元素和小于等于 \(0\)

分别暴力从前往后、从后往前枚举维护当前子串和,如果当前子串和小于等于 \(0\),那么就新开一段。

有解的情况可以是:

  • 从前往后可以划分出至少两段;

  • 从后往前可以划分出至少两段;

  • 两端可以划分出两段,且两段的并不为全集。

submission

D

题意:给定一个长 \(n\) 的排列 \(a\)。对这个排列进行操作,直到排列中只剩一个数:

  • 若这是第奇数次操作,那么删去所有不满足小于左右两边的数的元素;

  • 若这是第偶数次操作,那么删去所有不满足大于左右两边的数的元素。

现在给出每一个元素被删去的时间,请还原这个排列。

首先,我们凭直觉想到分析被删去的数是什么。(这是有一定道理的,因为显然没被删去的数限制更强,这是不利于我们构造的)

然后,我们先考虑偶数次操作:

删除的数满足其大于左右两边中至少一个数,这可以是 'V' 字型,也可以是楼梯型。但是出于懒惰,我们选择楼梯型。

那怎么保证楼梯型一定可以呢?

考虑一个最无脑的办法:让删去的数大于所有留下的数,这样就一定保证删去的数不是局部最大值/最小值。

从实现上,我们选择用剩余的数的一段前缀或后缀来填充被删去的数。

submission

E

题意:给定一个长 \(n\) 的数列 \(a\) 和一个整数 \(k\),你可以至多进行以下操作 \(3n\) 次:

  • 选择一对 \(i,j\) 满足 \(a_i+a_j=k\)

  • 选择一个数 \(x\),满足 \(x \in [0,k]\)

  • \(a_i \leftarrow x,a_j \leftarrow k-x\)

问你能否在限制次数内使得数列不降。

分析:

看到“序列不降”,想到给序列排序

排序就要想能不能实现 \(swap\) 函数。

我们想一想怎么样可以交换两个数 \(i,j\)

  • \(a_i+a_j=k\):显然;

  • \(a_i+a_x=k\):先操作 \(i,k\) 并将 \(a_i\) 赋值为 \(a_j\),然后再操作 \(k,j\)\(a_j\) 赋值为原来的 \(a_i\)

其它就不太好想了。

我们看第二种情况,有一个启发:我们不一定要直接交换两个数,我们可以通过一些“中转点”来实现交换。

  • 若存在 \(i,j\) 满足 \(a_i+a_j=k\),我们可以交换任意 \(x,y\) :具体地,先交换 \(i,x\),再交换 \(j,y\),此时 \(a_x+a_y=k\),直接交换即可。

那么我们按值从小到大,将值交换到最后一个有序的数的下一个位置。

可以证明这样总是可以的。

F

看不懂,鸽了。

posted @ 2025-08-29 13:42  XiaoZi_qwq  阅读(4)  评论(0)    收藏  举报