Codeforces试题乱做 Part1

终于开第一个乱作 \(\text{Part}\) 了, 开工大吉!


\(\text{[CF884E]Binary Matrix}\)

\(\color{green}{\text{[EASY]}}\)

数连通块个数, 就会有不少想法, 例如找代表元之类的.

但是, 看到这题的行列关系只和上下两行和相邻列. 所有可以考虑, 并查集数联通块个数.

只用记录上一行的值, 滚动数组即可. 用并查集来记录合并关系.


\(\text{[CF1438E]Yurii Can Do Everything}\)

\(\color{green}{\text{[EASY]}}\)

这题好诈骗啊, \(brute \; force\) 好啊.

这题还是教育到我了, 异或的优先级居然这么低.

先考虑暴力, 枚举左右端点, \(\mathcal{O}(n^2)\) 的复杂度.

输入格式考虑优化这个暴力, 很套路的, 只考虑左端点比右端点大的情况, 再从左往右从右往左各做一遍.

异或有一个很优秀的性质, \(a \oplus b < 2^{hight+1}\) , 其中 \(hight\)\(a\)\(b\) 的最高位.

所以我们可以考虑优化这个暴力了.

由于 \(a_l \geqslant a_r\) 所以当总和大于 \(2^{hight+1}\) 的时候退出枚举就好了.

考虑什么时候会推出, 最劣情况也会是经过两个最高位和 \(l\) 相同的数就会退出, 因为经过两个这样的数 \(2^{hight}+2^{hight}=2^{hight+1}\) 不合法.

我们按位考虑, 设最高位为 \(i\) 的数的位置集合为 \(b_i\) .

那么总共会枚举到的所有数的最坏情况就是 \(\sum\limits_{i=1}^k{\sum\limits_{j=1}^x{b_{i,j+2}-b_{i,j}}}\) 这个值的上界是 \(2n\) . 所以这个暴力实际上是线性的, 复杂度 \(\mathcal{O}(n)\) .


\(\text{[CF512D]Fox And Travelling}\)

\(\color{green}{\text{[EASY]}}\)

首先环上的边一定不会被遍历到.

用类似拓扑排序的方法把环上的点全部扔掉, 剩下的点会构成若干个有根树和无根树, 其中有根树的根是与环上相连的点.

对每棵树求出答案, \(01\) 背包合并即可, 合并时只需乘个组合数.

对于求每棵树的答案, 就是树上背包, 设 \(f_{i,j}\)\(i\) 的子树中选 \(j\) 个的方案数.

对于无根树, 对树上每个点做一边树上背包这样会发现有的方案被多计算 \(size-i\) 次, 其中 \(size\) 为这棵无根树的大小.

总时间复杂度 \(\mathcal{O}(n^3)\) .


\(\text{[CF1016F]Road Projects}\)

\(\color{green}{\text{[EASY]}}\)

自己秒的 \(\color{red}{2600}\) , 真高兴啊, 虽然是水题.

首先答案不可能超过原树上 \(1\)\(n\) 的距离.

显然树的形态是一个链, 然后链上的结点最多只有除链以外的一个儿子.

如果有超过一个儿子, 那么就可以直接连边, 使得答案为 \(1\)\(n\) 的链的距离.

否则, 设点 \(x\) 能到达的非链的最远距离为 \(a_x\) , 链上点 \(1\)\(x\) 的距离为 \(dis_x\) , 到那么答案一定为 \(\min\{dis_n,dis_n+dis_x-dis_y+a_x+a_y\}(x < y)\) .

显然是最大化 \((a_x+dis_x)+(a_y-dis_y)\) 这个 \(\mathcal{O}(n)\) 的计算就好了.


\(\text{[CF1146F]Leaf Partition}\)

\(\color{blue}{\text{[NORMAL]}}\)

这题好厉害啊, 为啥有人说是入门好题啊, 我不能接受.

考虑最终树的形态, 会是若干个不相交的子树以及一些未染色的点.

还是考虑在树上 \(dfs\) 然后合并的形式, 考虑一棵子树的根有哪些可能.

  1. 被染色, 且染相同颜色的儿子数为 \(1\) , 记方案数为 \(f_x\) .
  2. 被染色, 且染相同颜色的儿子数为大于等于 \(2\) , 记方案数为 \(g_x\) .
  3. 未被染色, 记方案数为 \(h_x\) .

这里解释一下为什么要分开 \(1\)\(2\) , 因为 \(1\) 不能做为染色了的树的根, 但 \(2\) 可以.

接下来考虑转移.

对于 \(f_x\) , 它可能是本身就选择好了一个染色的儿子, 也可能是选一个新的儿子染同色, 故为 \(f_x = f_x(g_y+h_y)+h_x(f_y+g_y)\) , 这里注意上面说的, \(f\) 不能作为一个新的根, 但 \(g\) 可以.

对于 \(g_x\) , 它可能本来都在一个染好色的子树里, 也可能是只有一个染同色的儿子, 新的为第二个, 故为 \(g_x = g_x(f_y+2g_y+h_y)+f_x(f_y+g_y)\) .

对于 \(h_x\) , 任何一边都不能染色, 故为 \(h_x = h_x(g_y+h_y)\) .


\(\text{[CF671D]Roads in Yusland}\)

\(\color{blue}{\text{[NORMAL]}}\)

如果说用 \(dp\) 做的话毫无疑问那是 \(\color{red}{\text{[HARD]}}\) 级别的, 因为实在太难, 但当你会了对偶, 这题就里所应当会做.

所以其实所有最大最小化的题不会就试试对偶, 反正没啥损失.

考虑对偶的式子 \(\max\{c^Tx|Ax \leqslant b\} = \min\{b^Ty|A^Ty \geqslant c\}\) .

其实就是构造出上面式子的.

  • \(c\) 为全 \(1\) 的列向量, 长度为 \(n-1\) .
  • \(y\)\(01\) 列向量, 长度为 \(m\) , 表示每条链选或者不选.
  • \(b^T\) 为长度为 \(m\) 的行向量, 表示每条链的代价.
  • \(A^T\) 为长 \(n-1\)\(m\)\(01\) 矩阵, 其中 \(A^T_{i,j}\) 表示 \(i\) 这条边是否在第 \(j\) 条链中.

所以现在的问题变成了构造一个 \(x\) 使得左式最大.

那就套路的找左式的意义, 实际上就是, 给每条边一个权值 \(x\) , 使得每条链上的权值之和不超过其代价.

方便思考, 我们把每条边的权值定义为选这条边的次数.

那么现在的问题就是, 在一个树上选若干条边(可重复), 给出一些链限制, 要求链上的边被选的次数不能超过这个限制, 使选择边数最大.

这是一个比较显然的贪心了, 先选深度大的, 能选就选, 选不了再选深度小的, 正确性显然, 用可并堆维护当前点到父亲这条边能选的最多次数.

最终复杂度 \(\mathcal{O}(n\log{n})\) .


\(\text{[CF739E]Gosha is hunting}\)

\(\color{blue}{\text{[NORMAL]}}\)

先考虑暴力 \(dp\) , 设 \(f_{i,j,k}\) 为考虑前 \(i\) 个, 用了 \(j\) 个第一种, \(k\) 个第二种的最大期望.

显然有 \(f_{i,i,k} = \max\{f_{i-1,j-1,k}+a_i,f_{i-1,j,k-1}+b_i,f_{i-1,j-1,k-1}+1-(1-a_i)(1-b_i)\}\) .

这个是 \(\mathcal{O}(n^3)\) 的朴素 \(dp\) .

我们发现多用一个精灵球肯定比不用的期望要大, 所以他是一个单调的东西, 不难发现 \(j\)\(k\) 中任意固定一位, 都是一个函数的凸函数, 所以考虑 \(wqs\) 二分.

我们讲状态化简为 \(f_{i,j}\) , 为考虑前 \(i\) 个, 用 \(j\) 个第一种的最大期望, 假设第二种可以无限使用, 那这样会有新的转移方程.

\[f_{i,j} = \max\{f_{i-1,j-1}+a_i,f_{i-1,j}+b_i,f_{i,j-1}+1-(1-a_i)(1-b_i)\} \]

时间复杂度 \(\mathcal{O}(n^2)\) .

这显然有问题, 不可能所有的转移都加上第二种的贡献, 所以可以给第二种加上一个价格, 即需要 \(k\) 元才能用一次第二种, 这样 \(dp\) 方程就会长这样,

\[f_{i,j} = \max\{f_{i-1,j-1}+a_i,f_{i-1,j}+b_i-k,f_{i-1,j-1}+1-(1-a_i)(1-b_i)-k\} \]

这样肯定就能有一些选不了. 这个就是 \(wqs\) 二分的板子了. 时间复杂度 \(\mathcal{O}(n^2\log{V})\) .

同理, 对于另一维也能这样二分, 最后复杂度为 \(\mathcal{O}(n\log^{2}{V})\) .


\(\text{[CF603E]Pastoral Oddities}\)

\(\color{green}{\text{[EASY]}}\)

不难发现点数为奇数的连通块一定不可行. 对于偶数个点的连通块直接找一棵生成树然后就一定能使度数为奇数. 像最小生成树的做法即可. 整体二分就行.


\(\text{[CF715E]Complete the Permutations}\)

\(\color{red}{\text{[HARD]}}\)

刚想觉得巨大神仙, 思考清楚之后感觉人力可及?总

根据经典结论, 这个距离就是 \(n-环数\) .

在一个不确定的置换中, 我们会产生 \(4\) 种边(链).

  • \(a \rightarrow b\)
  • \(a \rightarrow 0\)
  • \(0 \rightarrow b\)
  • \(0 \rightarrow 0\)

对于第一种我们可以简单的用并查集维护一下, 计算环的个数, 然后忽略这些边.

如果存在一组 \((0 \rightarrow b,a \rightarrow 0)\)\(a=b\) , 则合成边 \(0 \rightarrow 0\) .

处理之后记第二种第三种和第四种边的个数为分别为, \(n_1,n_2,m\) .

此外不可能存在一个环只包含第二种和第三种边, 一定是 \((0 \rightarrow 0,a \rightarrow 0)\) 或者 \((0 \rightarrow b,0 \rightarrow 0)\) 的形式然后链接起来.

并且我们考虑到这是置换, 所以 \((0 \rightarrow 0,a \rightarrow 0)\)\((a \rightarrow 0,0 \rightarrow 0)\) 其实是同一个, 但是前者不会改变 \(m\) , 合成之后变成 \((0 \rightarrow 0)\) , 所以考虑用前者来计数, 对于第三种和第四种同理.

在这里就应该很自然的想到分为内部消化和变成外部两种方案.

接下来我们形式化的表示出来我们的目标.

  • 将第二种链内部连成环, 或转化为第四类.
  • 将第三种链内部连成环, 或转化为第四类.
  • 将所有的第四类内部连接成环.

这就很自然的想到多项式了, 若成 \(c\) 个环就相当于在 \(x^c\) 上加权.

我们发现了 \((0 \rightarrow 0,a \rightarrow 0)\) 合成 \(0 \rightarrow 0\) , \((a_1 \rightarrow 0,a_2 \rightarrow 0)\) 合成 \(a_1 \rightarrow 0\) .

所以只要 \(0 \rightarrow 0\) 不成环, 第四种边的个数是不变的.

而第二种和第三种边之间不会相互转化, 所以三种转化之间是独立的, 于是分别考虑.

设第一种转化的多项式为 \(F_1\) .

\[F_1[k] = \sum_{i=k}^{n_1}{\binom{n_1}{i}\begin{bmatrix}i \\ k\end{bmatrix}(n_1-i+m-1)^{\underline{n_1-i}}} \]

意思是, 先选出 \(i\) 条链拼接成 \(k\) 个环, 剩下的转化成第四种边.

这种转化是不能留下第二种边的, 只能转化成若干条第四种边, 于是对于第一条待处理的边, 我们有 \(n_1-i+m-1\) 种连法, 连到第二种或者第四种的后面.

连完就消失, 所以是下降幂的形式.

同时要注意在 \(m=0\) 的时候, \(F_1[k] = \begin{bmatrix}n_1 \\ k\end{bmatrix}\) .

类似的考虑第二种转化记为 \(F_2\) .

最后考虑第三种转化, 记为 \(F_3\) .

\[F_3[k] = \begin{bmatrix}m \\ k\end{bmatrix}m! \]

总乘上 \(m!\) 是因为我们可以在原排列上任意顺序的填写这些边.

这题 \(n\) 较小, 把三个数组暴力卷起来即可, 复杂度 \(\mathcal{O}(n^2)\) .


\(\text{[CF542D]Superhero's Job}\)

\(\color{green}{\text{[EASY]}}\)

这题还真挺有教育意义的, 让我明白了一个道理, 面对这种 \(\Theta(1)\) 输入的题, 一定要多多观察性质, 如果它直接丢了个函数给你, 最好先看看它是不是积性函数和完全积性函数, 这样就有很多很好的性质了, 这点一定不能忘了.

不难证明这个函数是个积性函数, 也不难得出对于 \(p \in \mathbb{P},J(p^k) = p^k+1\) .

也就是说, 我们要把 \(A\) 表示成 \(\prod\limits_{i}{(p_i^k+1)}\) 的形式.

于是问题就变成了 \(A\) 有多少种不同的拆分方法.

众所周知, \(10^{12}\) 内, 约数最多的数有 \(6720\) 个约数, 并且大于 \(10^6\) 的约数最多就一个.

那么直接质因数分解就好了, 甚至不用 \(Pollard-rho\) , 根号拆就好了, 大数 \(Miller\; Rabin\) 即可.

接下来就是裸 \(dp\) 了.

\(f_{i,j}\) 表示考虑前 \(i\) 个质数, 合成 \(j\) 的方案数, 用 \(map\) 存就行.

复杂度 \(\mathcal{O}(\sqrt{A}+d(A)^2)\) .


完结撒花!!!

这个 \(\text{Part}\) 刚好一周完成, 所以其实是可以坚持下去的, 再加上这周还有 \(WC2022\) , 所以其实摆烂了很久.

这个 \(\text{Part}\) 的题总体来说还算满意, 虽然有的题我感觉有点摆烂, 但还算是说的过去.

不好高骛远, 但也不能只是轻触星空, 所以, 继续努力吧!!!

posted @ 2022-09-26 21:02  Lonely923  阅读(80)  评论(0编辑  收藏  举报