专栏文章

题解:CF1946F Nobody is needed

CF1946F题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miortpsd
此快照首次捕获于
2025/12/03 00:06
3 个月前
此快照最后确认于
2025/12/03 00:06
3 个月前
查看原文
毒瘤卡常,来写题解了。
设计 dp 状态 fl,rf_{l, r} 表示区间 [l,r][l, r] 中整除序列的个数,可知 dp 转移为 fl,r=lk<r[akar]fl,kf_{l, r}=\sum_{l \leq k < r} [a_k | a_r] f_{l, k},这样朴素 dp 的时间复杂度是 O(qn2)\mathcal{O}(qn^2) 的,卡常都过不了。而我们发现转移的 dp 状态第一维都是相同的,自然想到滚动第一维 ll
于是我们运用常用技巧,从 nn11 枚举 ll,对 ll 分组进行离线查询,我们可以运用线段树或者树状数组之类的做到 O(logn)\mathcal{O}(\log n) 单次询问。考虑从以 nn11 的顺序枚举 ll,我们希望可以以较优的时间复杂度将l+1l+1 为左端点时的 fl+1nf_{l+1 \cdots n} 转移为ll 为左端点时的 flnf_{l \cdots n}
此时 dp 转移上无法较显然的进一步优化,我们挖掘题目性质。我们发现由于加入了 ala_l 产生了以 ala_l 为第一个的整除序列使 ff 值改变:假设一个整除序列为 al,,ara_l, \cdots, a_r,则 frnfrn+1f_{r \cdots n} \leftarrow f_{r \cdots n} + 1。若我们对 ff 进行差分得到 hh,那么该整除序列相当于使 hrhr+1h_r \leftarrow h_r + 1。而由于 alara_l | \cdots | a_rara_rala_l 的倍数,我们发现:对于排列 aa至多只有不超过 nal\dfrac n{a_l}hih_i 会改变,而且每个 ala_l 均摊仅会使 O(logn)\mathcal{O}(\log n)hih_i 改变!
于是我们再维护一个 gig_i 来表示每次 hih_i增加量(第二次差分),我们发现:
0 & a_i \not| a_l\\ 1 & i=l\\ \sum_{a_j | a_i, j < i} g_j & a_i | a_l,i \neq l \end{cases}$$ 由于非零的 $g$ 较少,于是我们可以 $\mathcal{O}(\log^2 n)$ 枚举 $g_i$ 和 $g_j$ 进行转移。处理出 $g$ 值后,使用线段树进行 $\mathcal{O}(\log n)$ 次 $\mathcal{O}(\log n)$ 的修改操作,再维护 $\sum \sum g_i$ $\mathcal{O}(\log n)$ 查询,总时间复杂度 $\mathcal{O}(n \log^2 n+q \log n)$,不卡常不能过(也有可能是因为我程序天生常数大)。 接下来是一点奇怪的优化?卡常? 1. 用树状数组而非线段树,我不信有人能写线段树过了这题( 2. 预处理加入 $a_l$ 时会有哪些 $h_i$ 会变化,即提前枚举并存储好在 $a_l$ 右侧的 $a_l$ 的倍数。 代码仅供参考并安利博客:[here](https://www.cnblogs.com/LinkCatTree/p/19001352)。

评论

1 条评论,欢迎与作者交流。

正在加载评论...