adolphshi
文章17
标签11
分类4

一言

文章归档

CF1993 VP 记录

CF1993 VP 记录

CF1993.Codeforces Round 963 (Div. 2) solved(3/7)

A. Question Marks

题意

蒂姆正在做一个由 4n4n 个问题组成的测试;每个问题有 44 个选项:A"、“B”、"C "和 “D”。每个选项都有 nn 个正确答案,也就是说,有 nn 道题的答案是 “A”, nn 道题的答案是 “B”, nn 道题的答案是 “C”, nn 道题的答案是 “D”。

对于每道题,蒂姆都会把答案写在答题纸上。如果想不出答案,他会在该题上留下问号"?

他的答题纸有 4n4n 个字符。蒂姆最多能答对多少题?

思路

签到题

统计每一个选项,每一个选项与 nn 取 min 最后加和即可。

代码最后统一给出。

B. Parity and Sum

题意

给定一个由 nn 个正整数组成的数组 aa 。

在一次操作中,你可以选取任意一对索引 (i,j)(i, j) ,使得 aia_i 和 aja_j 具有不同的奇偶性,然后用它们的和替换较小的那个。更正式的说法是

  1. 如果 ai≤aja_i \leq a_j ,则用 ai+aja_i + a_j 替换 aia_i ;

  2. 否则,用 ai+aja_i + a_j 替换 aja_j 。

求使数组中所有元素具有相同奇偶性所需的最少操作数。

思路

我们可以发现,当奇偶性不同的时候,加出来的数一定是奇数,所以我们就是需要将所有的偶数变成奇数。我们还可以发现,当一个奇数大于一个偶数地时候,删掉偶数所需的操作次数为1,如果小于偶数的时候操作次数为2。所以为了减少不必要的操作,我们如下进行合并:

  1. 最大的奇数大于最小的偶数时,操作次数 +1+1 ,然后删掉这个偶数并累加到最大的奇数中。可以发现这样可以尽可能地减少当前奇数小于偶数的情况。

  2. 当最大的奇数小于最小的偶数时,选出最大的偶数,将它与这个奇数合并,可以发现这个操作最多只会被做一次,因为做完后会发现当前的数会大于所有的偶数。

代码写的很乱,有能力还是自己写。

C. Light Switches

题意

公寓由 nn 个房间组成,每个房间的灯最初都是关着的。

为了控制这些房间的灯光,公寓的主人决定在房间里安装芯片,这样每个房间正好有一个芯片,芯片安装在不同的时间。具体来说,这些时间由数组 a1,a2,…,ana_1, a_2, \ldots, a_n 表示,其中 aia_i 是在 ii /th房间安装芯片的时间(以分钟为单位)。

芯片安装后,每隔 kk 分钟就会改变房间的灯光状态–在 kk 分钟内开灯,然后在接下来的 kk 分钟内关灯,再在接下来的 kk 分钟内开灯,以此类推。换句话说, ii /th房间的灯光状态在 aia_i 、 ai+ka_i + k 、 ai+2ka_i + 2k 、 ai+3ka_i + 3k 、 …\ldots 分钟时由芯片改变。

公寓里所有房间最早亮灯的时刻是什么时候?

思路

这题看似很难,实则一点也不简单(指细节)

不难发现,每一个灯泡都是以 2×k2\times k 为一个周期的,所以我们可以先将所有输入的时间对 2×k2\times k 取模后再进行计算(注意在此时需要将取模前元素的最大值找出,方便统计)。

对于两个灯,如果它们两个存在某个时刻都亮了,那么它们的时间 [ai,ai+k][a_i,a_i+k] 与 [aj,aj+k][a_j,a_j+k] 必定有交集。同理,对于 nn 个时间点,如果它们存在一个时间都亮了,那么它们必定都在某个长度为 kk 的区间中,然而 kk 是很小的,所以可以从先前记录的最大值向后,判断所有点是否都在 kk 的区间中.

(这道题我赛时写的代码很烂,依旧是有能力的自己写)

D. Med-imize

题意

给定两个正整数 nn 和 kk 以及另一个由 nn 个整数组成的数组 aa 。

在一次操作中,可以选择 aa 的任意一个大小为 kk 的子数组,然后将其从数组中删除,而不改变其他元素的顺序。更正式地说,假设 (l,r)(l, r) 是对子数组 al,al+1,…,ara_l, a_{l+1}, \ldots, a_r 的操作,使得 r−l+1=kr-l+1=k ,那么执行此操作意味着用 [a1,…,al−1,ar+1,…,an][a_1, \ldots, a_{l-1}, a_{r+1}, \ldots, a_n] 替换 aa 。

例如,如果 a=[1,2,3,4,5]a=[1,2,3,4,5] ,我们对这个数组执行 (3,5)(3,5) 操作,它就会变成 a=[1,2]a=[1,2] 。此外,操作 (2,4)(2, 4) 的结果是 a=[1,5]a=[1,5] ,操作 (1,3)(1,3) 的结果是 a=[4,5]a=[4,5] 。

当 aa 的长度大于 kk (即 ∣a∣>k|a| \gt k )时,你必须重复操作。处理后,数组 aa 中所有剩余元素的最大中值 †^\dagger 是多少?

†^\dagger 长度为 nn 的数组的中位数是按非递减顺序排序后索引为 ⌊(n+1)/2⌋\left \lfloor (n+1)/2 \right \rfloor 的元素。例如 median([2,1,5,4,3])=3median([2,1,5,4,3]) = 3 、 median([5])=5median([5]) = 5 和 median([6,8,2,4])=4median([6,8,2,4]) = 4 。

思路

看见中位数,就首想二分答案,二分答案行不通再考虑上数据结构.这道题就是因为一看到中位数就想数据结构就寄了(😓).

所以这题是二分答案.我们选择二分剩余元素的最大中值 midmid 每一次二分中都将每一个大于 midmid 的值设成 11 ,小于 midmid 的值设成 −1-1 ,这样的话,我们只需要判断最后删下来的数最大值是否大于 00 即可.

extand

还有两个使用相同寄巧的题目:

P2824 HEOI2016/TJOI2016 排序

[AGC006D] Median Pyramid Hard

那么接下来难就难在如何求删掉剩下的数的最大值了.

考虑DP,但是在做DP之前,需要先知道一个 trick :

trick

对于一个序列,如果我们删去连续的一段,长度为 kk 那么剩余的序列下标在 (modk)\pmod {k} 意义下还是连续的.

证明很简单 [a1,a2…ai−1,ai…ai+k−1,ai+k…an][a_1,a_2\ldots a_{i-1},a_i\ldots a_{i+k-1},a_{i+k}\ldots a_n] 删去从 ii 开始的一段后成为 [a1,a2…ai−1,ai+k…an][a_1,a_2\ldots a_{i-1},a_{i+k}\ldots a_n] 而 i−1+1≡i+k(modk)i-1+1\equiv i+k \pmod k 所以tirck成立.

有了这个trick,我们会发现,最后剩下的数字下标会在1…k1\ldots k 最多出现一次,且一定按顺序排列.于是我们就可以推出DP转移方程:

dpi={max⁡(dpi−k,ai)i≡1(modk)max⁡(dpi−1+ai,dpi−k)otherwisedp_i= \begin{cases} \max(dp_{i-k},a_i) & i\equiv 1\pmod k \\ \max(dp_{i-1}+a_i,dp_{i-k}) & \text{otherwise} \end{cases}

解释一下,当i≡1(modk)i\equiv 1\pmod k 时,一定为数列的第一项,所以有选择不选\选.

其余情况就是选当前点或删去.

E. Xor-Grid Problem

题意

给定一个大小为 n×m(n,m≤15)n \times m (n,m\leq 15) 的矩阵 aa ,其中每个单元格都包含一个非负整数。位于矩阵第 ii 行与第 jj 列交点上的整数称为 ai,ja _{i,j} 。

让我们把 f(i)f(i)和g(j)g(j) 分别定义为第 ii 行和第 jj 列中所有整数的 XOR。在一次操作中,您可以

  1. 选择任意行 ii ,然后为每个 1≤j≤m1 \le j \le m 指定 ai,j:=g(j)a_{i,j} := g(j) ;或

  2. 选择任意一列 jj ,然后为每个 1≤i≤n1 \le i \le n 赋值 ai,j:=f(i)a_{i,j} := f(i) 。

对矩阵的第 22 列进行操作的示例。

在本例中,当我们对列 22 执行操作时,这一列中的所有元素都会发生变化:

  1. a1,2:=f(1)=a1,1⊕a1,2⊕a1,3⊕a1,4=1⊕1⊕1⊕1=0a_{1,2} := f(1) = a_{1,1} \oplus a_{1,2} \oplus a_{1,3} \oplus a_{1,4} = 1 \oplus 1 \oplus 1 \oplus 1 = 0

  2. a2,2:=f(2)=a2,1⊕a2,2⊕a2,3⊕a2,4=2⊕3⊕5⊕7=3a_{2,2} := f(2) = a_{2,1} \oplus a_{2,2} \oplus a_{2,3} \oplus a_{2,4} = 2 \oplus 3 \oplus 5 \oplus 7 = 3

  3. a3,2:=f(3)=a3,1⊕a3,2⊕a3,3⊕a3,4=2⊕0⊕3⊕0=1a_{3,2} := f(3) = a_{3,1} \oplus a_{3,2} \oplus a_{3,3} \oplus a_{3,4} = 2 \oplus 0 \oplus 3 \oplus 0 = 1

  4. a4,2:=f(4)=a4,1⊕a4,2⊕a4,3⊕a4,4=10⊕11⊕12⊕16=29a_{4,2} := f(4) = a_{4,1} \oplus a_{4,2} \oplus a_{4,3} \oplus a_{4,4} = 10 \oplus 11 \oplus 12 \oplus 16 = 29

这些运算可以多次进行。然后,我们将所有相邻单元格对的绝对差值相加,计算出最终矩阵的 beauty\textit{beauty} 值。

更正式地说,如果所有单元格 (x,y)(x, y) 和 (r,c)(r, c) 相邻,则 beauty(a)=∑∣ax,y−ar,c∣\textit{beauty}(a) = \sum|a_{x,y} - a_{r,c}| for all cells (x,y)(x, y) 。如果两个单元格共用一条边,则视为相邻单元格。

求所有可得矩阵中最小的 beauty\textit{beauty} 。

思路

手玩样例可以发现,我们选择任意两行,做两次操作后就会发现他们两行互换了,并且整体的异或值不变,对于列同理.

于是我们就可以考虑将每行\列的异或值求出,并添加一个新的列\行来存储,这样就变成了一个 (n+1)×(m+1)(n+1)\times(m+1) 的矩阵,然后每一个操作就变为了交换矩阵中任意两行或列的元素.问题就变成了选择 nn 行 mm 列,求最小的 beauty\textit{beauty} .

extand

这种异或的寄巧还有一道题

[AGC016D] XOR Replace

注意到 n,m≤15n,m\leq 15 考虑状压,不难发现,行和列是可以分开考虑的,行对值的贡献与列对值的贡献之和就是答案,因此我们可以分开考虑(常用寄巧).

extand

也有使用这种技巧的题目,大多与相邻的值有关,行和列不一定是同一种算法.

P2258 [NOIP2014 普及组] 子矩阵 此题是将行 dfs 再将列 dp

CF1202C You Are Given a WASD-string… 此题是将行列分开考虑,然后分别DP\前缀和

我们设 gi,jg_{i,j} 代表将第 ii 行接在第 jj 行后面的代价,显然这是可以 O(n3)O(n^3) 预处理的.

我们首先枚举我们不选的列 nlnl 然后对行进行DP

设 dpS,idp_{S,i} 代表已选择的状态 SS 和最后一次选择第 ii 行的答案,那么就不难推出转移:

dp_{S\cup\{j\},j}=\min \limits_{j\notin S}\{dp_{S,i}+g_{i,j}-\abs{a_{i,nl}-a_{j,nl}}\}

我们记 ansi,nlans_{i,nl}为不选择第 ii 行不选第 nlnl 列的答案,这个不难能得到.

对于列,枚举不选的行后同理即可.(只是注意 ansans 的下标即可)

F2. Dyn-scripted Robot (Hard Version)

题意

这是问题的困难版本。唯一不同的是,在这个版本中 k≤1012k \le 10^{12} 。只有两个版本的问题都解决了,你才能进行hack。

给定 OxyOxy 平面上有一个 w×hw \times h 矩形,矩形的左下方有点 (0,0)(0, 0) ,右上方有点 (w,h)(w, h) 。

您还有一个最初位于点 (0,0)(0, 0) 的机器人和一个由 nn 个字符组成的脚本 ss 。每个字符都是 L、R、U 或 D,分别指示机器人向左、向右、向上或向下移动。

机器人只能在矩形内移动,否则将更改脚本 ss 如下:

  • 如果试图向垂直边界外移动,它会将所有 L 字符改为 R 字符(反之亦然,将所有 R 字符改为 L 字符)。

  • 如果尝试向水平边界外移动,则会将所有 U 字符更改为 D 字符(反之亦然,将所有 D 字符更改为 U 字符)。

然后,它会从无法执行的字符开始执行更改后的脚本。

机器人移动过程的示例, s="ULULURD"s = \texttt{"ULULURD"} 。

脚本 ss 将被连续执行 kk 次。即使重复执行,字符串 ss 的所有变化都将被保留。在此过程中,机器人总共会移动到 (0,0)(0, 0) 点多少次?注意,初始位置不计算在内。

思路

先给一个提示:本题为数论题,算法是 ExCRT.

好,我们首先要知道这个反转是怎么做的.我们从一位的情况开始考虑,碰到边缘反弹其实就是将走出去的部分镜像.

所以我们可以把它当成反转当成镜像空间内行走,这样的话题目就变成了会经过多少次横纵坐标都为2w2w 和 2h2h 倍数的点.

我们设重复完一次指令后的坐标位于 (dx,dy)(dx,dy) 那么我们实际上要求的就是对于当前指令的第 ii 位所在的点 (sx,sy)(sx,sy) 求解有多少个解满足:

{dx×x+sx≡0(mod2w)dy×y+sy≡0(mod2h)\begin{cases} dx\times x+sx\equiv 0 \pmod{2w}\\ dy\times y+sy\equiv 0 \pmod{2h} \end{cases}

其中 x≤kx\leq k .

可以发现,我们只需要求解出一个最小整数解后剩下的统计就是 ⌊k−x0−1m⌋\lfloor \frac{k-x_0-1}{m}\rfloor其中 mm 为模数.

我们将它改造成exgcd的标准模式,使用exgcd合并两个方程即可求出最小正整数解.

code

s

本文作者:adolphshi
本文链接:http://adolphshi.github.io/2024/09/19/cf1993-vp-%E8%AE%B0%E5%BD%95/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可