复健训练1
ABC320
第一场复健VP!
发现没有ex题了,很震惊,发现到E题还是水题,更震惊。
可能有新手保护机制,做C的时候把hard(G)看了,本来抱着试一试的心态,结果发现会了!
第一次打了网络流,调了半天...
之后没时间看F了,感觉是个经典题...
赛后想了F题,还是做出来了,是一个不错的题:
- 在直线上往返一次,直接dp会有后效性,怎么办?
- 将往返过程都记成状态!
ABC317
觉得320太简单了,在kenko上随便找了一个看起来难一点的,就开了。
结果发现还是我太naive了...
做到F就不会了...
而且发现打的比较慢,这也体现了复健的重要性!(毕竟为了把XCPC的路费打回来!都是钱啊!)
F - Nim
题面
给定四个正整数 \(N,A_1,A_2,A_3\),试求满足一下条件的三元组 \(\left(X_1,X_2,X_3 \right)\) 的个数,对 \(998244353\) 取模。
- \(1 \le X_i \le N,i=1,2,3\)。
- \(A_i \mid X_i\),\(i=1,2,3\)。
- \(\left(X_1 \bigoplus X_2 \right) \bigoplus X_3=0\)。
其中:$ 1\ \leq\ N\ \leq\ 10^{18} , 1\ \leq\ A_i\ \leq\ 10 $
题解
反正当时做这个题的时候是一脸懵逼了..
因为整除和异或为 \(0\) 的两个条件完全关联不到一起去...
但只要想到这一点整个题目就有思路了,我们一次考虑每一个二进制位,也就是数位dp,来满足异或的条件,同时维护 \(x_i\bmod a_i\) 的余数,为了维护 \(3\) 个 \(x_i\) ,我们得设 \(f[n][b_1][b_2][b_3][0/1][0/1][0/1]\) 表示考虑到第 \(n\) 个二进制位,每个 \(i\) 的余数,和是否碰顶,之后就是数位dp的做法了。
启发
- 对于二进制的运算,我们可以拆数位来考虑,由此可以结合数位dp来做
- 对于 \(a\) 是 \(b\) 的倍数之类的条件,若 \(b\) 很小,那么 \(a\bmod b\) 的结果种类就很小。
CF1882
快速过前四题,被E1/2坐牢了。
做D的时候一下子没看出来换根DP,顺便补了一下新的换根dp方法。
现在回忆一下做E1的时候,感觉没有仔细想了?不过确实,现在做有一定难度的题会有些抵触。
不过当时做E1的时候就只差一点点了...
E. Two Permutations
题面
有两个排列 \(\{a_n\},\{b_m\}\)。每次你可以执行以下操作:
- 选择两个正整数 \(i,j\),将排列 \(A_1a_iA_2\) 修改为\(A_2a_iA_1\),排列 \(b\) 同理。
构造一组操作使得同时满足 \(a_i=i,b_j=j\)。如果无解,输出 \(−1\)。
你不需要(E2需要最小化)最小化操作次数。你只需要保证你的操作数量不超过 \(10^4\) 。
\(n,m\le 2000\)。
E1题解
-
构造方法:\(AB[i]Cj\to C[j]iAB\to iABjC\),这样就把 \(i\) 与 \(A\) 连在了一起,这样让 \(i\) 从 \(n\to 1\),就行了。
-
如何让 \(a,b\) 步骤相等?
先设我们随便一种操作使 \(a\) 复原步骤数为 \(N\),\(b\) 的为 \(M\)
- \(1,n\) 的两步操作,这样可以处理 \(N,M\) 同奇偶的情况。
- \(N,M\) 同奇偶?那我们可不可以调整一下 \(N\) 的奇偶?
- 我们做 \(n\) 步 \(1\) 操作,如果 \(n\) 为奇数就可以了。
- \(n,m\) 都是偶数怎么办?可以证明这样一定无解。
- 通过分析一步操作对逆序对数的改变可以得到,若 \(n\) 为偶数,那么任意一次操作,都会使 \(\{a_n\}\) 逆序对的奇偶性发生变换。
- 而最后 \(\{a_n\}\) 是确定的,所以其步骤数的奇偶性也是确定的。
E2题解
现在就是人类智慧题了。
CF1870
快速过了前四道,然后被E搞坐牢了....
看了题解确实感觉自己做题很生疏了,想dp,但发现是 \(O(n^3)\) 就放弃了,其实是可以好好想想怎么优化的(虽然也不一定想得出来)
E. Another MEX Problem
题面
给你一个序列 \(a\),让你选出一些不交的子串,使得它们的 \(\text{mex}\) 的异或和最大。
\(n\le 5000,a_i\le n\le5000,a_i\le n\)
题解
有官方题解的做法,感觉启发性有限,Luogu题解区里有相关题解。
首先要明确主方向是DP,因为此题中的异或和是没办法拆位算的,而且 \(n,a_i\le 5\times10^3\),数据范围也支持你DP,那么至少要多想想DP!
设 \(f_{i,j}\) 表示考虑到前 \(i\) 位异或和为 \(j\) 是否可行,转移考虑下一个子串,复杂度是 \(O(n^3)\) 的。
注意这是一个可行性的dp,我们很有可能把一维给消掉的。
消 \(j\) ?用 bitset
?好像不行。
试试 \(i\)?这能怎么消?注意到一旦 \(f_{i,j}\) 为 \(1\),那么 \(i\) 后面的所有 \(f_{k,j}\) 都为 \(1\) !,那么我们就可以改成设 \(g_j\) 表示 \(f_{i,j}=1\) 的最小的 \(i\) 。
那么现在怎么转移?枚举 \(k\) ,看在 \(i\) 右边且 \(\text{mex}=k\) 的区间中右端点最小是什么,就可以转移了。
启发
- 将可行性的DP通过后缀全为 \(1\) 的性质优化一维
CF1879
做得还行,做D的时候脑抽了,忘记了经典的 \(\sum_{i=1}^n\sum_{j=i+1}^na_i\oplus a_j\) 模型的一点扩展....
想了半天才过。
后面可以想问题了,而不是看到standing里的performance就开摆,把E过掉了。
赛后想F,\(2e5\) 觉得根号能过,尴尬了看了sol,很有启发!
F. Last Man Standing
题面
现在有 \(n\) 个怪,第 \(i\) 个怪有属性 \(a_i,b_i\)。
对于一个攻击力为 \(x\) 的人,第 \(i\) 个怪存活的时间为 \(b_i\lceil\frac{a_i}x\rceil\)。
对于每一个 \(i\),找到一个 \(x\),使得其单独存活的时间最长。
其中:\(n,a_i,b_i\le 2\times 10^5\)。
题解
看到 \(\lceil\frac{a_i}x\rceil\),想到整除分块枚举结果,对于一个结果 \((l,r,st)(\forall i\in[l,r],\lceil\frac{a_i}i\rceil=st)\),暴力是记录到 \(l\sim r\) 上,但是我们可以直接记录到 \(r\) 上,然后将后缀合并。
对于 \(n\),所以怎么得到 \((l,r,st)\)?
向下取整的分析是一样的(终于搞懂了为什么在整除分块中 r=n/st
了)
但是!\(n\sqrt n\) 的复杂度是不能接受的!吐了!
下面是高端的官方sol
我们枚举 \(x\),然后枚举 \(\frac{a_i}{x}\) 的值 \(j\),然后我们只要得到 \(a_i\) 在 \(x(j-1)+1\sim xj\) 范围内 \(b_i\) 的最大值和次大值就可以了!!!这个可以用st表实现。
这样就是一个经典的 \(O(n\log n)\) 的复杂度!
启发
- 知道了整除分块的原理。
- 遇到 \(\lfloor\frac{a_i}{x}\rfloor\) 的问题可以先枚举 \(x\),再枚举 \(\lfloor\frac{a_i}{x}\rfloor\)的值,实现一个 \(n\log n\) 的总枚举复杂度。