CF359D Pair of Numbers

发布时间 2023-09-19 14:42:31作者: FOX_konata

原题

翻译

感谢\(xjk\)提供,%%%

先说一个带\(\log\)的做法

首先,区间满足条件的要求即为\(\min_{i=l}^{r}{a_i} = gcd_{i=l}^{r}{a_i}\),这是显然的(我甚至想错了QwQ)

我们考虑固定住这个区间的最小值\(x\),我们发现假如一个区间\([L,R]\)满足条件,则\([L,R]\)的子区间\([l,r]\)必然满足条件。这样我们就证明了区间长度是有单调性的。(注意这里我并不是真的让钦定一个最小值\(x\),这里这一步只是证明了长度有单调性)

因此我们考虑二分长度答案,接下来的问题就变成了判断区间\([i-x,i]\)\(gcd\)是否等于\(\min\),我们直接用\(st\)表即可实现

最终复杂度\(O(n (\log{n} + \log{A}) )\),这个复杂度的来源参考这里


然后我们考虑不带\(\log\)的做法

我们考虑固定住这个区间的最小值\(x\),我们发现假如一个区间\([L,R]\)满足条件,则\([L,R]\)的子区间\([l,r]\)必然满足条件。这样我们就证明了区间长度是有单调性的。

既然我们都想了固定区间最小值\(x\),那我们为什么不直接找到\(x\)向左向右延申时能延申到的最远距离呢?

因此我们考虑设\(l_i,r_i\)分别表示从\(i\)开始,保证区间\([l_i,i]\)\([i,r_i]\)中所有数都能被\(a_i\)整除的最小\(l_i\)和最大\(r_i\)。因此最终答案即为\(r_i - l_i\)

因此我们考虑怎么求出\(l_i\)\(r_i\),暴力的,我们可以考虑二分+\(st\)表找\(gcd\)的方法,但这并不优秀

我们能够发现一个性质:如果一个数\(a_i\)能整除一个区间\([l,r]\),则\(a_i\)的因数一定可以整除区间\([l,r]\)(这不废话吗)

因此我们考虑用\(kmp\)的思路:初始赋值\(l_i=i\),如果\(a_{l_i-1} | a_i\),则我们让\(l_i \leftarrow l_{l_i-1}\)

\(r_i\)同理,注意最后统计答案时判断重复的区间即可

最终复杂度\(O(n)\)