Loading

CF/AT 选记

ABC383G

\(f_i\) 表示恰好选了 \(i\) 段的答案,感性理解发现 \(f\) 实际上是上凸的。

考虑分治优化。对于当前区间 \([l,r]\),设 \(f_{i,j,x}\) 表示最左边选了 \(i\) 个,最右边选了 \(j\) 个,有完整的 \(x\) 段时的答案。
区间的合并即枚举跨过左右两边的那一段的情况,做 \((\max,+)\) 卷积。用闵可夫斯基和即可做到线性。
总复杂度 \(O(nk^2\log n)\)

实现时需要注意细节。分治到区间长度小于 \(2k\) 时直接暴力做会比较好写。
code

ABC333F

参见 https://www.luogu.com.cn/article/af2cis77

\(f_{i,j}\) 表示共有 \(i\) 个人时,第 \(j\) 个人存活的概率。

考察 \(f_{i,1}\)。如果杀了第一个人,那就没有然后了;否则他会被移到最后一个,而总人数没有变化。
所以有 \(f_{i,1}=\frac 1 2 f_{i,i}\)

考察 \(f_{i,j}(j\gt 1)\)。如果杀了第一个人,那么总人数减一,\(j\) 前进一位变为 \(j-1\);否则总人数不变,\(j\) 仍然前进一位。
所以有 \(f_{i,j}=\frac 1 2 f_{i-1,j-1}+\frac 1 2 f_{i,j-1}\)

发现转移成环。考虑直接将转移式看做方程,解出 dp 值即可。复杂度 \(O(n^2)\)
code

ARC187B

碰见连通块数这种看起来就很不好刻画的东西,大体的思路要么是把它换成另一个好算的东西,要么是手玩一些小数据分析性质,看看它是否等价于另一个东西。

仔细分析可以发现每个连通块都是一个区间。
证明:假设存在一个连通块,包含了 \(i\) 左边的某些点,也包含了 \(i\) 右边的某些点,但不包含 \(i\)。设这个连通块从 \(i\) 左边连向右边的某一条边为 \(L\to R\),则可以发现无论 \(a_i\) 取何值,\(i\) 至少与 \(L,R\) 中的一个有连边。

进一步地,考察什么时候两个区间无法合并。显然是当且仅当左边区间的最小值大于右边区间的最大值。
于是对于一个给定序列 \(a\),其连通块数为 \(1+\sum_{i=1}^{n-1}[\min a[1,i]\gt \max a[i+1,n]]\)

对每个 \(i\) 分别计算贡献即可。这部分是容易的。
复杂度 \(O(nm)\)
code

ARC187C

对于这种题目给了一个神秘操作然后要在这个操作的基础上计数等等的题,先考虑分析操作本质,把它变成一个容易刻画的东西。

下文所提及的“前缀最大值”均不包括第一个元素。

对于本题,我们发现操作实际上是对于每个前缀最大值,将它移动到下一个前缀最大值之前。

显然前缀最大值经过此操作后仍然是前缀最大值,而且 \(n\) 一定被移到了最末尾。
于是,对于一个给定的 \(Q\),如果 \(n\) 没有出现在末尾,则它对应的答案为 \(0\);否则,设其前缀最大值集合为 \(S\),则可以取 \(S\) 的任意子集作为操作中向后移动的元素,那么这就唯一对应了一个 \(P\),所以其对应的答案为 \(2^{|S|}\)

现在问题形式看起来就很可做了。考虑 dp,设 \(f_{i,j}\) 表示考虑到 \(i\),当前前缀最大值为 \(j\) 的答案,考虑转移:

  1. \(Q_i\ne -1\)
    • \(\forall j\gt Q_i, f_{i,j}\gets f_{i-1,j}\)
    • \(\forall j\lt Q_i, f_{i,Q_i}\gets f_{i-1,j}\times 2\),注意如果 \(i\lt n\) 但是 \(Q_i=n\) 则没有这个转移。
  2. \(Q_i=-1\)(以下转移在 \(i\lt n\)\(j\) 都不应取到 \(n\)):
    • 如果更新不改变前缀最大值,设小于等于 \(j\) 且未被填的数有 \(c_j\) 个,则 \(\forall j, f_{i,j}\gets c_j\times f_{i-1,j}\)\(c_j\) 即未被钦定位置的小于等于 \(j\) 的数的数量减去前缀 \(-1\) 数量。
    • 如果更新前缀最大值,\(\forall j, f_{i,j}\gets \sum_{k\lt j} f_{i-1,k}\times 2\),前缀和优化一下即可。

复杂度 \(O(n^2)\)
code

ABC270H

设计数器当前的数字为 \(b_i\)。记状态 \(f_i\) 表示 \(i=\max_{j=1}^n a_j-b_j\) 时期望还需要的操作次数。
则初始有 \(f_0=0\),所求即 \(f_{a_n}\)

考虑转移,有

\[f_i=1+\frac 1 n\sum_{j=1}^n f_{\max(a_j,i-1)} \]

\(c_i\) 为小于 \(i\)\(a\) 的个数,则有

\[f_i=1+\frac 1 n(c_if_{i-1}+\sum_{j=c_i+1}^n f_{a_j}) \]

又有

\[\begin{aligned} f_{i+1} &=1+\frac 1 n(c_{i+1}f_i+\sum_{j=c_{i+1}+1}^n f_{a_j}) \\ &=1+\frac 1 n(c_if_i+\sum_{j=c_i+1}^n f_{a_j}) \end{aligned} \]

下式减上式可得

\[f_{i+1}-f_i=\frac{c_i}n(f_i-f_{i-1}) \]

\(g_i=f_i-f_{i-1}\),则上式相当于 \(g_{i+1}=\dfrac{c_i}ng_i\),所求的 \(f_{a_n}=\sum_{i=1}^{a_n} g_i\)
又由第一个式子可知 \(f_{a_n+1}=1+\dfrac 1 n n f_{a_n}=1+f_{a_n}\),所以 \(g_{a_n+1}=1\)
考虑反着递推出所有的 \(g_i\) 并求和。发现 \(g\) 实际上由 \(n-1\) 个等比数列组成,可以 \(O(n\log P)\) 完成求和。
code

ARC186B

简单题,但具有启发意义。

我们发现想要建出一个序列的笛卡尔树,实际上只需要知道每个位置前面第一个比它小的位置。

所以此题给的条件足以建出笛卡尔树。然后就只需要求把这个排列填到笛卡尔树上的方案数,直接计数即可。
code

ARC186C

较简单的贪心题。

首先考虑给球的那个人的策略。他肯定会先把所有颜色的球各给一个,从而逼着另一个人一直买新的盒子。然后他肯定是追着容量最小的那个盒子塞球,这样同样可以让另一个人快点买新盒子。
然后考虑买盒子的人的策略。基本策略就是要按容量从大到小选。
假设我们已经确定了要买哪些盒子,那么根据上述策略,前 \(m-1\) 大的盒子只放一个球,其他盒子都放满了。那么收益就是容量前 \(m-1\) 大的 \(1-p\) 之和,加上其余的 \(v-p\) 之和。

贪心维护一下就好了。复杂度 \(O(n\log n)\)
code

ARC186A

神仙转化。
典中典之网格转二分图。不同的是这题需要构造出一个有向图,即 0 和 1 连边的方向相反。那么两个矩阵相似的充要条件就是图中每个点的入度出度情况一样。
发现如果连出了一个环,那么把环上所有边反向,不影响任何点的度数情况。
进一步地,固定点的充要条件是这条边不属于任何环。

观察数据范围,考虑高维 dp。
\(f_{i,j,k}\) 表示左部点用了 \(i\) 个,右部点用了 \(j\) 个,选了 \(k\) 条环边是否可行。
转移即新加入一个强连通分量,\(f_{i,j,k}\gets f_{i-x,j-y,k-xy}\)
bitset 优化一下,复杂度 \(O(\frac{n^6}{\omega})\)
code

ARC187E

待补。

ARC186D

首先分析符合条件的序列的性质。

  • \(\sum a_i=n-1\)
  • \(a_n=0\)
  • 不存在一个真前缀符合条件。也即 \(\forall i\in[1,n),\sum_{j=1}^i a_j\ge i\)

考虑转化到格路上。也就是从 \((0,1)\) 开始,每次先向上走 \(a_i\) 格,再向右走一格,最后走到 \((n-1,n)\),且要求不能碰到直线 \(y=x\)
由于有字典序的限制,直接枚举与原串的 LCP 和当前要向上走的格数,那么只需计算从当前的 \((x,y)\) 走到 \((n-1,n)\) 的方案数。这个可以反射容斥。

由于枚举的向上走的个数总和是 \(O(n)\) 的,所以总复杂度也是线性。
code

ABC389F

由于每次的增量至多为 1,感性理解一下可以发现,答案一定是关于 \(X\) 单调的。
所以用线段树直接维护即可。

ABC389G

此题给了一个小启发:对限制条件与最短路有关的图计数时,可以考虑模拟 bfs 的过程,逐层加点,边则显然只能从本层连向上一层或本层,得到一个高次方的 dp。

具体对于这题,就是考虑记 \(f_{i,j,k,lst,0/1}\) 表示偶数层共 \(i\) 个点,奇数层共 \(j\) 个点,已有 \(k\) 条边,最后一层有 \(lst\) 个点且为奇数还是偶数层的方案数。转移就是新加入一层点,可以预处理出 \(g_{i,j,k}\) 表示上一层有 \(i\) 个点,新加的这一层有 \(j\) 个点,新一层与上一层及本层共连 \(k\) 条边的方案数。枚举新加的点数与边数,单次转移 \(O(n^3)\)

总时间复杂度就是 \(O(n^8)\) 的,dp 过程中仔细控制一下枚举的上下界,常数就可以非常小。
code

ARC190C

先考虑原问题咋做。显然是 dp,记 \(f_{i,j}\) 表示 \((1,1)\sim(i,j)\) 的答案,有 \(f_{i,j}\gets a_{i,j}(f_{i-1,j}+f_{i,j-1})\)

发现改了一个格子后,它右下方的所有 dp 值都得改,显然是不可接受的。
注意到 dp 转移依赖于相邻格子,每次修改的格子也相邻,所以考虑让查询尽量只与修改的格子相关。
再记 \(g_{i,j}\) 表示 \((i,j)\sim(n,m)\) 的答案,那么假设修改的是第 \(x\) 行的格子,只需 \(f_{x,*},g_{x+1,*}\) 即可算出答案。
所以只需要每次重算修改的格子所在行的 \(f,g\) 值,即可保证正确性。

如果给定的 \(n\lt m\),那么交换行和列,即可保证复杂度是根号的。
code

posted @ 2024-12-12 21:14  Accelessar  阅读(2)  评论(0)    收藏  举报