Codeforces试题乱做 Part3
啊, 时间过的好快啊, 最近考试好多, 改题让我时间好少, 还是希望能多做点自己想做的题, 那就卷一点吧.
这个 $\text{Part}$ 怎么也得省选前搞定吧.
$\text{[CF1097G]Vladislav and a Great Legend}$
$\color{blue}{\text{[NORMAL]}}$
啊, 好的, 我以后知道怎么算 $\sum\limits_{n}{f(n)^k}$ 这种东西了.
这个考虑组合意义就行.
其实 $x^k$ 这种形式不一定只有斯特林数一种思路, 如果只想斯特林数早晚得寄.
推导式子可得,
外面枚举 $i$ 肯定没毛病, 那就考虑里面那个组合数怎么做, 考虑其组合意义, 对于每一个点集组成的生成树, 在树里面选 $i$ 条边染色的方案数.
设 $f_{x,i}$ 表示 $x$ 的子树内选出一个有 $i$ 条边被染色的非空生成树的方案数.
类似树形背包的转移, 但这个树形 $dp$ 有点细节我觉得, 很容易就会忘记考虑新的子树和父亲的边.
考虑新加入一个子树, 那么:
- 只有原来的子树.
- 只有新的子树 (加上 $x\rightarrow y$ 这条边).
- 原来的和新的共同组成 (加上 $x \rightarrow y$ 这条边).
时间复杂度 $\mathcal{O}(nk)$ .
$\text{[CF679E]Bear and Bad Powers of 42}$
$\color{blue}{\text{[NORMAL]}}$
因为 $42$ 的幂次越往大越在值域内的就越少, 线段树维护每个数到 $42$ 的幂次差多少, 以及区间 $\min$ , 若当前最小值小于要加的数, 那就递归下去暴力修改.
区间赋值也是好做的, 标记下传的时候注意顺序即可.
定义连续段的势能为值域内大于其值的 $42$ 的幂的个数, 那么一次操作最多会被递归 $\log_{42}{nV}$ 次. 单次操作复杂度为 $\mathcal{O}(\log_{42}{nV}\log{n})$ .
总体复杂度为 $\mathcal{O}(q\log_{42}{nV}\log{n})$ .
$\text{[CF889E]Mod Mod Mod}$
$\color{red}{\text{[HARD]}}$
令 $g(x,i) = x \bmod a_1 \bmod a_2 \bmod a_3 \dots \bmod a_i$ .
发现, 只要 $\forall i,g(x,i) \not = 0$ , 则有 $\forall i,g(x-1,i)=g(x,i)-1$ , 也就只要保证 $x \bmod a_i$ 都不是 $0$ , 可以随意降低 $x$ , 都不影响 $g(x,i)$ 之间的相对差.
设 $f(i,R)=y$ 表示如果 $x \bmod a_i$ 最后变成了 $0 \sim R$ , 这时多出来的部分的最大值都可以是 $y$ .
这时可以设计 $dp$ , 用 $map$ 存二元组 $(R,y)$ , 在 $i$ 处枚举所有二元组试图使其适配 $a_{i+1}$ .
- 如果 $R < a_{i+1}$ , 则二元组不变.
- 否则可以直接延展到 $a_{i+1}$ , 变为 $(R \bmod a_{i+1},y’)$ .
- 如果 $R \geqslant a_{i+1}$ , 可以把 $R$ 降低到 $a_{i+1}-1$ , 使得 $i+1$ 成为卡着上界的地方, 变为 $(a_{i+1}-1,y’’)$ .
除了以上转移方案, 其他方式都不能保证 $R$ 存在一个位置卡满上界.
一共只会产生 $n$ 个新的 $R$ , 故复杂度为 $\mathcal{O}(n\log{a_i}\log{n})$ .
$\text{[CF571D]Campus}$
$\color{blue}{\text{[NORMAL]}}$
感觉这种集合合并的东西总能并查集离线做, 下次要牢记这种套路.
合并时新建一个虚电, 先把森林建出来, 问题就转化为两个森林分别子树加, 子树赋值.
注意到我们对于每个点只用关注它查询之前最后一次赋值为 $0$ 的时间以及之后的子树加, 询问就变成了区间求和, 树状数组维护即可.
时间复杂度 $\mathcal{O}(n+m\log{n})$ .
$\text{[CF1332G]No Monotone Triples}$
$\color{red}{\text{[HARD]}}$
这题首先要看出 $b$ 不会太长, 不能超过 $4$ .
证明大概是分类讨论, 用 $Dilworth$ 定理证明.
我们可以预处理出 $1 \sim n$ 中的每个 $i$ 作为 $b_1$ 时, 最近的 $b_3$ 或 $b_4$ 在哪.
这样对于每组询问只需要 $ST$ 表维护一下 $[l,r]$ 中最小值和最小位置, 判断一下最小位置是否在 $\leqslant r$ 即可.
分类讨论 $3,4$ ,
存在一个长度为 $3$ 的 $b$ , 只需要序列 $a$ 在 $[l,r]$ 中不单调.
对于每一个 $i$ , 处理出在它前面第一个不同于 $a_i$ 的位置 $pre_i$ , 和后一个不同于 $a_i$ 的位置 $nxt_i$ , 如果有 $(a_i-a_{pre_i})(a_{nxt_i}-a_i) < 0$ , 则存在一个长度为 $3$ 的 $b\{a_{pre_i},a_i,a_{nxt_i}\}$ .
在 $b_1=pre_i$ 上记录一个可能的 $b_3=nxt_i$ , $ST$ 表维护即可.
存在一个长度为 $4$ 的 $b$ , 需要满足 $b_1,b_4$ 既不是 $b$ 中的最大值, 也不是最小值.
从前往后维护一个单调不降的单调栈 $stk_1$ 和一个单调不升的单调栈 $stk_2$ .
为了使 $b_1,b_4$ 不成为 $b$ 中最大或最小值, 不难推出 $b_4$ 需满足两个条件,
- $b_4$ 既不在 $stk_1$ 中, 也不在 $stk_2$ 中.
- 在 $b_4$ 之前存在一个 $x$ 在 $stk_1$ 中, 且满足 $a_x \not= a_{b_4},x > b_1$ , 存在 一个 $y$ 满足 $a_y \not= a_{b_4},y > b_1$ .
也就是找到 $stk_1$ 中第一个严格大于 $a_{b_4}$ 的位置 $gt$ 和 $stk_2$ 中第一个严格小于 $a_{b_4}$ 的位置 $lt$ , 然后在 $(\max\{gt,lt\},n]$ 中找到即不在 $stk_1$ 中也不在 $stk_2$ 中的最小位置, 这就是符合条件的最小 $b_4$ , 可以用 $set$ 维护.
时间复杂度 $\mathcal{O}(n\log{n}+q)$ .
$\text{[CF453E]Little Pony and Lord Tirek}$
$\color{green}{\text{[EASY]}}$
考虑到如果一个位置曾变为 $0$ 那它的贡献是好算的, 如果一段全是 $0$ , 那这一段的贡献都是好算的.
这让我们联想到分块.
预处理出每个块 $i$ 从 $0$ 开始 $j$ 个单位时间后的和, 我们称一个块是未被限制的当且仅当它在某一时刻被清零, 且未被单点修改过, 这些块可以预处理出答案直接计算贡献, 否则一个块称为被限制的, 暴力计算贡献.
一开始所有块都是被限制的, 每次修改至多将两个块变成限制的, 所以复杂度均摊下来并没有问题.
预处理是采用两次前缀和, 时间复杂度 $\mathcal{O}(\frac{n^2}{B})$ , 其中 $B$ 为块长, 块长需自己调整, 以卡空间, 当然也可以通过技巧做到线性.
$\text{[CF643G]Choosing Ads}$
$\color{blue}{\text{[NORMAL]}}$
摩尔投票法, 受教了.
傻子也看的出答案不能超过 $5$ 个.
首先考虑 $p\geqslant 51$ 的情况, 也就是要求区间绝对众数, 摩尔投票法是这样的, 维护当前众数和它的血量 $HP$ , 每次新加入一个数, 如果它和现在的众数相等, 那么 $HP+1$ , 否则 $HP-1$ , 如果 $HP$ 变为 $0$ 了, 那么它就寄了, 用杀掉它的数来当新的众数, 其 $HP$ 变为 $1$ , 最后剩下的数就是可能的答案.
正确性也比较显然, 如果一个数超过了一半也不可能被别的数干寄.
然后推广到 $p=20$ 的情况, 维护当前 $5$ 个众数和 $HP$ , 合并两个区间就拿两个区间的 $10$ 个众数暴力合并就行了.
线段树维护即可, 时间复杂度 $\mathcal{O}(nk^2\log{n})$ , 其中 $k=\lfloor \frac{100}{p} \rfloor$ .