(本文是基于队爷 @s_r_f 所写题解的完善和补充)
可以发现,如果我们暴力地枚举一个数的因数或倍数,时间复杂度是可接受的。
对于前者,单次复杂度为 O ( n ) O(\sqrt n) O(n);对于后者,由于题目保证了 C ≤ 10 C \leq 10 C≤10,所以单次的均摊复杂度应为调和级数 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