6294. 2019.08.10【NOIP提高组A】动态数点
Description
一个长度为 n n n的序列 { a n } \{a_n\} {
an}。如果对于一段区间 [ L , R ] [L,R] [L,R],存在 L ≤ k ≤ R L ≤ k ≤ R L≤k≤R使得 a i ∈ [ L , R ] a_i \in [L,R] ai∈[L,R]都有 a k ∣ a i a_k| a_i ak∣ai,我们认为它有价值,价值为 R − L R - L R−L;若不满足条件则没有价值)。求所有区间中价值最大为多少,最大价值的区间有多少个,以及这些区间分别是什么。
n ⩽ 1 0 5 n\leqslant 10^5 n⩽105
Solution
关键算法: S T \mathsf {ST} ST表,二分
30pts
直接上暴力模拟, 枚举每一个区间, 时间复杂度 O ( n 3 log n ) O(n^3\log n) O(n3logn)。
60pts
枚举一个左端点, 然后开一个桶, 再往右扫过去。
每一次加入一个数更新一下当前的 gcd \gcd gcd, 然后看区间中是否存在这个数。 时间复杂度 O ( n 2 log n ) O(n^2\log n) O(n2logn)
100pts 做法
开始用 S T \mathsf {ST} ST表预处理一下区间 gcd \gcd gcd, 以及区间最小值。
二分区间长度, 然后每一次 c h e c k \mathsf{check} check扫过去,看是否有区间最小值和 gcd \gcd gcd相等。 时间复杂度 O ( n log 2 n ) O(n \log_2 n) O(nlog2n