Codeforces试题乱做 Part5

(闲话)有一说一 \(tabby\) 配个 \(Ubuntu\) 倒是好看, 就是配起来巨大阴间, 交互很困难, 而且局限性也有点大.


\(\text{[CF917C]Pollywog}\)

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

我觉得算不上困难, 看到数据就能想到做法了, 就是状态不好设计, 需要找出一个有 \(n\)\(dp\) , 并且可以写成矩阵形式.

\(f_{i,s}\) 表示区间为 \([i-k+1,i]\) , 编号范围仅有 \(i-x+1,x\in s\) , 不难写出转移, 再写乘矩阵形式, 用那些套路的技巧.

不过值得注意的一点是, 有用的状态只有 \(\dbinom{k}{x}\) 个, 最大为 \(70\) , 大大的优化了复杂度.

时间复杂度为 \(\mathcal{O}(\omega^3\log{n}+\omega^2p\log{n}+\log{p})\) .


\(\text{[CF776G]Sherlock and the Encrypted Data}\)

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

确实思路比较自然, 看到这种莫名其妙的东西肯定得玩玩这个函数的性质的. 不难发现这个只和 \(\max{d}\) 有关, 考虑直接 \(dp\) .

\(f_{i,j,k}\) 表示考虑了前 \(i\) 位( \(16\) 进制下), 是否已经有 \(d_x=\max{d}\) , 是否顶到上界, 裸的数位 \(dp\) 即可.

时间复杂度 \(\mathcal{O}(q\omega^3)\) .


\(\text{[CF1517F]Reunion}\)

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

可能也并没有难到这种程度吧, 只是我确实搞不出来.

先对题面计数方法进行转化, 设一种方案为 \(S\) , 表示有空的点集, 半径为 \(f(S)\) , 答案为 \(n-1+\sum\limits_{r=1}^{n-1}{r\sum\limits_{S\not=\varnothing \land S \not= U}{[f(S)=r]}}\) , 改写为 \(\sum\limits_{r=1}^{n-1}{\sum\limits_{S}{[f(S)\geqslant r]}}\) , 因为对于一般的 \(dp\) 限制, 大于等于总是比等于更容易满足的.

枚举半径, 那就是求解后面那个东西了, 设有空的是白点, 没空的是黑点.

\(f_{i,j}\) 表示以 \(i\) 为根的子树内部距离 \(i\) 最近的黑点距离为 \(j\) 的方案数, 我们称满足了子树内部限制的点为预备点, 预备点还应满足子树外的限制.

为此, 我们再设 \(g_{i,j}\) 表示 \(i\) 的子树内最深的预备点与 \(i\) 的距离为 \(j\) 时的方案数, 如果最深的都满足不了, 那么更浅的一定不满足.

合并树上背包类似, 初始化为 \(f_{i,0}=g_{i,0}=1\) , 设当前合并结点 \(i\) 与其子结点 \(x\) .

  • 合并 \(f_{i,j}\)\(f_{x,k}\) , 转移到 \(f_{i,\min\{j,k+1\}}\) .
  • 合并 \(f_{i,j}\)\(g_{x,k}\) , 若 \(j+k+1 > r\) 则转移到 \(g_{i,k+1}\) , 否则转移到 \(f_{i,j}\) .
  • 剩下两个同理.

答案即 \(\sum\limits_{i=0}^{n}{g_{rt,i}}\) , 总复杂度为 \(\mathcal{O}(n^3)\) .


\(\text{[CF848D]Shake It!}\)

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

好题, 但感觉实际上应该没那么难, 不过真的很容易想偏, 如果考虑的是最小割就一去不复返了.

最小割等于最大流, 我们考虑在 \(s\rightarrow t\) 这条边加入一个点 \(x\) , 那就会出现两条新的边 \(s\rightarrow x\) , \(x\rightarrow t\) . 考虑分别把 \(s,x\) 当成新的原点和汇点, 考虑子问题, 同理 \(x,t\) . 设 \(s\rightarrow x\) 产生的流量为 \(f_1\) , \(x\rightarrow t\) 产生的流量为 \(f_2\) , 则点 \(x\) 产生的贡献为 \(\min\{f_1,f_2\}\) , 拆成子问题, 就方便 \(dp\) 了.

\(f_{n,m}\) 表示初始有两个点 \(s,t\) 和一条边 \(s\rightarrow t\) , 进行 \(n\) 次操作之后得到最大流为 \(m\) 的图的数量, 再设 \(g_{n,m}\) 表示初始有三个点 \(s,t,x\) 和两条边 \(s\rightarrow x,x\rightarrow t\) , 进行 \(n-1\) 次操作之后得到最大流为 \(m\) 的图的方案数.

转移 \(g\) 就是考虑两边的子图分别长什么样, \(g_{n,m}=\sum\limits_{k=0}^{n-1}{\sum\limits_{\min\{x,y\}=m}{f_{k,x}f_{n-1-k,y}}}\) , 其中 \(\min\) 卷积可以通过后缀和做到线性, 即 \(sumg_{n,m} = \sum\limits_{k=0}^{n-1}{sumf_{k,m} \cdot sumf_{n-1-k,m}}\) , 再差分一遍即可求出 \(g\) .

转移 \(f\) 是考虑每种 \(g_{i,j}\) , 如何构成它, 有多少个, 对他的贡献, \(f_{n,m} \leftarrow f_{n-ki,m-kj}\dbinom{g_{i,j}+k-1}{k}\) .

转移的时候先转移 \(g\) , 从小到大算, 先 \(n\)\(m\) , 转移 \(f\) 类似多重背包转移, 这样就不会算重了.

时间复杂度为 \(\mathcal{O}(n^4\ln{n})\) , \(\ln{n}\) 是枚举 \(k\) 时的调和级数.


\(\text{[CF1654F]Minimal String Xoration}\)

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

挺诈骗的吧, 并不是很难, 很像 \(SA\) .

\(f(x,k)\) 表示取 \(x\) 作为异或值时得到的前 \(2^k\) 个字符的字符串, 那么显然有:

\[f(x,k)=f(x,k-1)+f(x\bmod 2^{k-1},k-1) \]

其中加号表示字符串拼接.

从小到大来的话, 每次都可以确定一个长度为 \(2^{k-1}\) 的段, 并且这些段内部的顺序已经确定, 按照 \(SA\) 的思路做就行.

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


\(\text{[CF343E]Pumping Stations}\)

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

会最小割树就会做, 不会就不会.

大概就是最小割树建出来, 发现一个树里最小的那条边经过次数要经量少, 那条边会把树分成两个连通块, 剩下两个也是树, 也就是走完一个连通块再去走另一个, 递归即可.


\(\text{[CF1616G]Just Add an Edge}\)

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

这个评分只是尊重一手 \(3500\) , 其实并没有那么困难, 但这题还是挺巧妙的.

首先判断本身就有哈密顿路径的情况.

如果我们要填一条边 \(x\rightarrow y\) , 等价于原图存在一条以 \(x\) 为终点的路径和一条以 \(y\) 为起点的路径, 他们不交且并集为全集.

为方便处理添加两个点 \(0\)\(n+1\) , 其中 \(0\) 在以 \(x\) 为终点的路径中, \(n+1\) 在以 \(y\) 为起点的路径中.

把以 \(x\) 为终点的路径的点权值赋为 \(0\) ,另一个路径的点的权值赋为 \(1\) , 形成一个 \(01\) 串.

容易发现 \(s_0,\dots,s_{y-1}\) 都是 \(0\) , \(s_{x+1},\dots,s_{n+1}\) 都是 \(1\) (这个地方发憨了, 没想到) .

考虑固定 \(y\) 之后怎么做, 我们只关心 \(s_i \not= s_{i+1}\) 的情况, 所以设 \(f_{i,w}\) 表示是否可能满足 \(s_{i-1}=w\) , \(s_{i}=w\oplus 1\) , 转移是 \(trivial\) 的, 考虑每个点从那个地方走过来的即可, 时间复杂度 \(\mathcal{O}(nm)\) .

考虑优化, 设 \(p\) 为第一个位置满足 \(l\)\(l+1\) 之间没有连边, 那么有 \(s_l\not= s_{l+1}\) .

所以 \(f_{l+1}\) 是我们状态转移的必经之路, 我们可以以 \(l+1\) 为分界线, 对 \([0,l+1]\)\([l+2,n+1]\) 分别 \(dp\) , 其值可以表示成只和 \(f_{l+1}\) 有关的形式, 然后再合并两边信息即可, 需特判可以加一条 \(x<y\) 的边的情况.

时间复杂度 \(\mathcal{O}(n+m)\) .


\(\text{[GYM102012C]Rikka with Consistency}\)

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

看到范围就知道是高维 \(dp\) , 设 \(f_{x,y,z}\) 表示第一个人在 \([x,x+1]\) 段, 第二个人在 \([y,y+1]\) 段, 高度为 \(z\) 的最短路径, 转移每次考虑高度不变或者加减 \(1\) 即可.


\(\text{[CF1344E]Train Tracks}\)

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

发现是相当于有 \(\mathcal{O}(n^2)\) 个条件 \((t,x,y)\) , 把 \(t\) 排序即可, 至此我们得到一个 \(\mathcal{O}(n^2\log{n})\) .

发现排序之后, \(x\)\(y\) 相同的条件是无意义的, 故删掉, 删掉之后会神奇的发现, 条件数变为了 \(\mathcal{O}(n\log{n})\) , 时间复杂度变为了 \(\mathcal{O}(n\log^2{n})\) .

证明大致为调轻边时才加条件, 证明同树上启发式合并复杂度, 故总数为 \(\mathcal{O}(n\log{n})\) .


\(\text{[CF1017G]The Tree}\)

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

发现没有操作二的时候, 可以直接给点加权, 维护后缀最大值做, 考虑在有操作二时怎么做, 子树赋值加单点赋值, 时间复杂度 \(\mathcal{O}(n\log^2{n})\) .


这段时间做 \(\text{topcoder}\) 的题较多, 鸽了很久, 暑假要疯狂卷!

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