九月杂记
初赛初赛~~~~~
板刷 CF
CF2135B *1700
做一做人类智慧。
想到的:应该是通过与一些特殊的锚点进行计算,然后得到机器人的初始坐标。能否让机器人先一直往上走,然后这样就可以得到它与最高的那个锚点的曼哈顿距离,然后再让它一直往右走,得到它与最右边的那个锚点的曼哈顿距离,最后通过一些计算得到初始坐标?
待续……
CF1935D *1800
想到的:可以浅推一下式子吗?即设 \(x+y=c_i\),则 \(c_i-x=y\);\(y-x=c_i\),则 \(x+c_i=y\)。也就是说我们只需要找出这两种可能的数对 \((x,y)\),然后用总数减掉这些数量即可。那会有同时满足:\(x+y=c_i\) 和 \(y-x=c_i\) 的吗?当 \(x=0,y=c_i\) 时才会出现,所以最后加上 \(n\) 即可。如果有 \(x+y=c_i\),\(y-x=c_j\) 的情况出现呢?\(x=(s_i-s_j)\div 2\),\(y=(s_i+s_j)\div 2\)。那我们只需要把原来的所有的不满足题意的数对求出来,然后容斥一下就结束了?感觉还有一些细节。
待续……
分治
CF2146D2 *2000
想到的:首先贪心的考虑,对于两个数 \(x\) 和 \(y\),必然是当 \(x\) 或 \(y\) 后二进制里全为 \(1\) 是最优的,在下文中我们称其为互补。
对于一段区间 \([l, r]\),在去除二进制中相同的高位后,必然可以被划分成两个区间 \([l, pos]\) 与 \((pos, r]\),其中第一个区间中的数在二进制表示下的最高位为 \(0\),第二个区间中的数在二进制表示下的最高位为 \(1\)。此时,不妨令 \(pos - l + 1 \ge r - pos\)。在这种情况下,\((pos, r]\) 这段区间中的数一定可以与第一个区间中进行互补匹配,于是将匹配的数计算进答案,然后令 \(r\leftarrow 2\times pos - r\),将区间右边界缩小。若 \(pos - l + 1 < r - pos\),则令 \(l\leftarrow 2\times pos - l + 2\)。
没想到的:写法稍显复杂。
ds
CF2137F *1900
想到的:数数题。考虑一段区间中怎样必须把 \(z_i\) 赋值成 \(x_i\)。显然,当 \(x_i>\max(x_l,x_{l+1},\cdots ,x_{i-1})\) 时要把 \(z_i\) 赋值成 \(x_i\)。所以就是要找到一个数的左边的第一个大于等于它的数,然后用这段长度(不包含比它大的数)乘上 \(x_i\) 即可,不过 \(x_i\neq y_i\)。直接单调栈就行了吧?不对,还有一些很大的问题。因为要前缀最大值相同,但如果在 \(y_i>\max(x_1,x_2,\cdots, x_i)\) 情况下,这是非法的。所以再直接 \(\operatorname{ST}\) 二分找一下第一个满足 \(x_j>y_i\) 的 \(j\) 即可。\(j\) 的范围是 \(1\sim 单调栈所找到的位置\)(就当是 ds 题了)。
没想到的:无。
图论
CF1915G *1800
最短路跳到的题目。
想到的:贪心的考虑,每次一定会用现有的最快的自行车。同时,注意到 \(n\le 1000\) 这启发我们用 \(n^2\) 的状态。 设 \(dis_{i, j}\) 表示走到点 \(i\) 且此时最快的单车的速度为 \(j\) 的最小时长。
没想到的:无。
CF1383A *1700
想到的:注意到每次只能把字母往大的改,所以无解很好判。然后考虑统计极长连续子串的个数,即为答案。怎么假了?c,原来是选择子序列……难不成是图论建模?
没想到的:注意到可以把每个字母与其要变成的字母之间连一条边,那么原图必为 DAG,所以任意一颗生成树便能满足条件。并差集即可。
CF2135C *2000
这题在赛时听到了一点思路?不过并不影响……
想到的:注意到样例给的都有环,所以考虑在环上的点的性质。注意到环上的点必须相等,且奇环上的点一定要为 \(0\)。此时考虑算出边双,然后对于每个边双进行 dfs 统计答案。代码实现好复杂啊!
CF2137G *2200
想到的:\(\operatorname{DAG}\) 上的博弈论,为什么都说比 F 简单?
没想到的:第一次做类似的题,需要考虑在先手取和后手取的先手必败或先手必胜状态。即 \(f_{i,0}\) 表示先手取的状态,\(f_{i,1}\) 表示后手取的状态,转移如下:
- \(f_{u,0}=\operatorname{OR}_{v\in G_u}\{f_{v, 1}\}\)
- \(f_{u,1}=\operatorname{AND}_{v\in G_u}\{f_{v, 0}\}\)
然后,每次把节点染成红色就相当于把 \(f_{u,0}\) 和 \(f_{u,1}\) 都赋值成 \(0\)。最后注意到每个点只会被染色一次,没了。
dp
CF2143D1 *1800
想到的:注意到一个性质,只有在选出来的序列中的最长下降子序列的长度 \(\le 2\) 时才合法。考虑枚举开头的点,然后进行 dp 转移。状态可以这样设计:\(f_{i,j}\) 表示以 \(i\) 结尾,且最长下降子序列为 \(j\) 的序列个数。
不一定是 dp 啊。似乎可以直接暴力枚举下降的子序列中的数,然后找到所有比子序列中最大的数大的数的数量,设其为 \(x\),则贡献加上 \(2^x\)。仍有一些问题,考虑枚举两个位置 \(i\) 和 \(j\),并且有 \(a_i>a_j\)。然后找到 \(i\) 之前的数中有多少个比 \(a_i\) 小的,找到在 \((i, j)\) 之中有多少个比 \(a_i\) 大的,找到在 \(j\) 之后中有多少个比 \(a_j\) 大的。设其总和为 \(x\),\(ans\leftarrow ans + 2^x\)。不对,这样有可能会不合法,枚举完 \(i\),\(j\) 后直接对于三个段暴力 dp,但这样是 \(n^4\) 的,跑不过去啊啊啊啊啊啊啊啊! 还要去个重……
没想到的:什么?三维 dp?\(f_{i,j,k}\) 表示在 \(1\sim i\) 中有全局最大值为 \(j\) 且此时二元组第二个最大为 \(k\)。(真的要全局最大值啊)……
CF1225E *2200
模拟赛赛题,写的比较糖……
想到的:乱 dp,直接前缀和+二分优化。
没想到的:注意到一条路径一定有很多个拐点,所以考虑从每个拐点向该行或列最后一个可以走到的点进行转移(这东西赛时想到了的),这可以差分优化一下。然后判断最后一个点直接前缀和即可。因为每个点都可以从上面或右边走过来,所以状态定义为:\(f_{i,j,0/1}\)。
CF1935C *1800
想到的:感觉可以 dp,但要优化。设 \(f_{i,j}\) 表示 dp 到第 \(i\) 个数且第 \(i\) 个数是现在集合里的第 \(j\) 个数的最小花费。发现不好转移。难不成只能贪心了?看了一下 tag,还真是前缀和优化 dp……等会,是不是可以先排序,然后就不用考虑需要在中间转移的情况了。可以以 \(b_i\) 为关键字从小到大排序,然后转移方程就变成了:
把和 \(k\) 有关的东西提出来,得到:
所以每次转移只需要维护一下长度为 \(j-1\) 的集合的最小值即可。按顺序转移,还是很妙的。
没想到的:就排序那一步是看了一下 hint……
数学
CF2137E *1500
想到的:没什么好说的,纯纯无聊分讨题,corner cases!!!
CF2140C *1500
想到的:类似这样操作的题目一般都有一个 trick 就是在同一种状态最优状态下不断重复拉扯。但这题有一个问题就是如果不断拉扯那么 \(f(a)\) 与 \(cost\) 有关,所以要尽量早的结束。于是问题转换为在 Alice 进行第一次操作后的 \(f(a)_{max}\)。 考虑 Alice 的操作方式。如果 Alive 目前的序列是最优解,那么选择两个最远的且下标奇偶性相同的数交换。有两个式子:
- \(a_r-a_l+r-l=(a_r+r)-(a_l+l)\)
- \(a_l-a_r+r-l = (a_l-l)-(a_r-r)\)
所以只要分前后两边扫,然后分别算出这两个式子的最大值即可。为什么 WA on test 3?改一下式子:
- \(2\times a_r-2\times a_l+r-l\)
- \(2\times a_l-2\times a_r+r-l\)
求这个最值就行了。
板刷 luogu
P12684 \(\color{green}绿\)
想到的:第一眼注意到这东西好像是有单调性的?然后可以 bfs 一次求出最少的使用步数。并不具备单调性,而且 \(5000\times 5000\) 很大啊。
没想到的:第一次直接 01bfs 优化即可,然后第二次的转移条件相当于加了一个一定要是最短路上的边进行转移,然后再跑一边 01bfs 就行了……
P6005 \(\color{green}绿\)
想到的:类似 dp 之类东西?设 \(f_{i, j}\) 表示第 \(i\) 天走到 \(j\) 能获得的最大价值。有转移如下:
没想到的:状态设计看了一眼题解。
模拟赛
26
a
思路:对于开头的长度为 \(k\) 的序列,我们发现可以用它把后面的 \(n-k\) 位都改变,同理,我们如果使用后 \(k\) 那么我们可以把所有的前面的 \(n-k\) 位都改变。所以如果前 \(k\) 和后 \(k\) 都没有交集,那么必然每一个位置都可以被改变,如果有交集呢?那么交集中的部分不管怎么改,两两之间的相对情况都不会改变,所以交集必须全部相同。此时,问题便转换成了求中间的最长的相同的子串。
b
思路:注意到 \(k\le 1000\),所以可以对于左下角的点枚举其所在 \(k\times k\) 的方格中的位置,然后判断其它点的位置。但这样的复杂度是 \(O(n\times k^2)\) 的,显然会 TLE,怎么优化呢?考虑一个转化,那就是可以对于每个 \(x\) 和 \(y\) 都对 \(2\times k\) 取模,然后把白色的点的坐标改成 \((x+k, y)\),这样就变成了黑点。此时,我们枚举左下角的点可能在的 \(2k\times 2k\) 中位置,然后用二维前缀和取统计一下就行了。细节稍多。
c
思路:贪心的考虑,让最外端的字符进行匹配,这样一定不劣,然后每次匹配完一对字符后边可将其删除,即不用再考虑它们了。然后就是怎样维护每次操作后剩下的字符的位置,发现每次将 \(s_i\) 移动到末尾 \(n\),那么只需要知道 \(i\sim n\) 中有多少个字符即可,这可以使用线段树维护,每次匹配完一对字符后就把它们赋值成 \(0\)。唯一要注意的是单独一个字母在回文串中间的情况,这样后面的所有步骤都需要加一。
d
思路:没什么好讲的,状压板子。

浙公网安备 33010602011771号