Description
给定序列
a
=
(
a
1
,
a
2
,
⋯
,
a
n
)
a=(a_1,a_2,\cdots,a_n)
a=(a1,a2,⋯,an),定义
f
(
l
,
r
)
=
min
l
≤
i
<
j
≤
r
∣
a
i
−
a
j
∣
f(l,r)=\min\limits_{l\le i<j\le r} |a_i-a_j|
f(l,r)=l≤i<j≤rmin∣ai−aj∣.
q
q
q 次查询求
f
(
l
,
r
)
f(l,r)
f(l,r) 的值.
Limitations
2
≤
n
≤
10
5
2\le n\le 10^5
2≤n≤105
1
≤
q
≤
3
×
10
5
1\le q \le 3\times 10^5
1≤q≤3×105
1
≤
l
<
r
≤
n
1\le l<r\le n
1≤l<r≤n
3
s
,
512
MB
3\text{s},512\text{MB}
3s,512MB
Solution
分块做法,可以在线.
问题类似 P5046,考虑拆开贡献:
- 散块内部和散块之间
- 整块之间
- 散块和整块之间
显然答案为排序后的相邻项之差的 min \min min,所以对每个块维护排序后的结果 p i p_i pi.
对于单个散块,直接从 p i p_i pi 中取出原下标 ∈ [ l , r ] \in [l,r] ∈[l,r] 的数,扫一遍过去,复杂度 O ( B ) O(B) O(B).
对于两个散块,设 g ( l , r , L , R ) g(l,r,L,R) g(l,r,L,R) 表示 i , j ∈ [ l , r ] ∪ [ L , R ] i,j\in [l,r]\cup [L,R] i,j∈[l,r]∪[L,R] 时的答案,同样从对应两个块的 p i p_i pi 中取出,归并在一起扫一遍,复杂度也是 O ( B ) O(B) O(B).
对于散块和整块之间,维护以下数组:
- D 1 ( x , b ) D_1(x,b) D1(x,b): i ∈ [ L ( b ) , R ( bel ( x ) − 1 ) ] , j ∈ [ L ( bel ( x ) ) , x ] i\in [L(b),R(\operatorname{bel}(x)-1)],j\in[L(\operatorname{bel}(x)),x] i∈[L(b),R(bel(x)−1)],j∈[L(bel(x)),x] 时的答案.
- D 2 ( x , b ) D_2(x,b) D2(x,b): i ∈ [ x , R ( bel ( x ) ) ] , j ∈ [ L ( bel ( x ) + 1 ) , R ( b ) ] i\in [x,R(\operatorname{bel}(x))],j\in[L(\operatorname{bel}(x)+1),R(b)] i∈[x,R(bel(x))],j∈[L(bel(x)+1),R(b)] 时的答案.
怎么求呢?我们先枚举两个块
a
≠
b
a\ne b
a=b,求出单个位置
x
∈
[
L
(
a
)
,
R
(
a
)
]
x\in [L(a),R(a)]
x∈[L(a),R(a)] 对单个块
b
b
b 的答案(在
p
i
p_i
pi 上做双指针),然后前/后缀一下即可.
由于两个数组无交集,且空间占用大(都为
O
(
n
n
)
O(n\sqrt n)
O(nn)),实现时要合并成一个.
对于整块之间,维护
S
(
i
,
j
)
S(i,j)
S(i,j) 表示 第
i
∼
j
i\sim j
i∼j 块的答案,我们先求解单块答案,再用区间 dp 算出整个表.
查询时对每种贡献取 min \min min 就是答案,时间复杂度 O ( ( n + q ) n ) O((n+q)\sqrt n) O((n+q)n),空间复杂度 O ( n n ) O(n\sqrt n) O(nn).
需要一定卡常,实测加快读和 Ofast 就行,Submisson.
710

被折叠的 条评论
为什么被折叠?



