CF765F Souvenirs Solution

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)=li<jrminaiaj.
q q q 次查询求 f ( l , r ) f(l,r) f(l,r) 的值.

Limitations

2 ≤ n ≤ 10 5 2\le n\le 10^5 2n105
1 ≤ q ≤ 3 × 10 5 1\le q \le 3\times 10^5 1q3×105
1 ≤ l < r ≤ n 1\le l<r\le n 1l<rn
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 ij 块的答案,我们先求解单块答案,再用区间 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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值