P4224 [清华集训2017]简单数据结构 题解

本文详细解析了P4224问题的动态规划解决方案,探讨了在序列中进行不同操作时的时间复杂度,包括在序列两端插入和删除元素的策略。通过模拟操作,实现了O(qlog2m)的实际复杂度,其中涉及的数组fi和fcnti用于记录最长上升倍数子序列的长度和计数。代码实现中利用gi和len辅助数组优化了维护过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(本文是基于队爷 @s_r_f 所写题解的完善和补充)

可以发现,如果我们暴力地枚举一个数的因数或倍数,时间复杂度是可接受的。

对于前者,单次复杂度为 O ( n ) O(\sqrt n) O(n );对于后者,由于题目保证了 C ≤ 10 C \leq 10 C10,所以单次的均摊复杂度应为调和级数 O ( ln ⁡ n ) O(\ln n) O(lnn)

所以,我们可以考虑直接模拟题意中的操作。


首先,我们设 f i f_i fi 为以 i i i 开头的最长上升倍数子序列的长度。同时,为了方便统计答案的第二项,我们再设一个 f c n t i fcnt_i fcnti,表示有多少个 j j j 满足 f j = i f_j = i fj=i

有了以上两个数组,我们就可以从小到大枚举 i i i,当 f c n t i fcnt_i fcnti 不为 0 0 0 时,我们就同时找到了答案的第一项和第二项,一举两得。

没错!这样做的理论复杂度是 O ( n q ) O(nq) O(nq) 的,会超时。但这真的是实际的复杂度吗?

注意题目中有这样一句话:保证在任意时刻序列 A A A 非空,其中的元素互不相等

也就是说,就算是最坏的情况,这个子序列的长度也是不超过 O ( log ⁡ 2 m ) O(\log_2 m) O(log2m) 的,所以上述做法的实际复杂度为: O ( q log ⁡ 2 m ) O(q\log_2m) O(qlog2m)


解决完了询问,我们再看看四个操作中哪个最好想。

显然是在序列左端进行的两个操作。究其原因,我们先来推推 f i f_i fi 的转移方程式:

考虑枚举 i i i 的倍数 j j j,如果 j j j

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值