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

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

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

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

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

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

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


首先,我们设 fif_ifi 为以 iii 开头的最长上升倍数子序列的长度。同时,为了方便统计答案的第二项,我们再设一个 fcntifcnt_ifcnti,表示有多少个 jjj 满足 fj=if_j = ifj=i

有了以上两个数组,我们就可以从小到大枚举 iii,当 fcntifcnt_ifcnti 不为 000 时,我们就同时找到了答案的第一项和第二项,一举两得。

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

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

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


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

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

考虑枚举 iii 的倍数 jjj,如果 jjj 存在,设 jjj 的位置为 posjpos_jposj,则有:
fi=max⁡i∣j,posj>0{ fj+1} f_i = \max_{i | j, pos_j > 0}\{f_j + 1\} f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值