NOI2020 D1T3 时代的眼泪 口胡题解

Description

给定一个长度为 n n n 的排列 p p p,每次给定 l 1 , r 1 , l 2 , r 2 l_1,r_1,l_2,r_2 l1,r1,l2,r2,求 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] 中存在多少对 ( i , j ) (i,j) (i,j),满足:

i ≤ j i \le j ij
p i ≤ p j p_i \le p_j pipj
p i ∈ [ l 2 , r 2 ] p_i \in [l_2,r_2] pi[l2,r2] p j ∈ [ l 2 , r 2 ] p_j \in [l_2,r_2] pj[l2,r2]

1 ≤ n , q ≤ 1 0 5 1 \le n,q \le 10^5 1n,q105,时限 5s \texttt{5s} 5s,空限 1GB \texttt{1GB} 1GB

Solution

考虑分块,令块长为 ⌊ n ⌋ = B \lfloor \sqrt n \rfloor=B n =B

对于一次形如 L , R , l , r L,R,l,r L,R,l,r 的询问,我们将 [ L , R ] [L,R] [L,R] 划分为 [ L 1 , p − 1 ] [L_1,p-1] [L1,p1] [ p , q ] [p,q] [p,q] [ q + 1 , R ] [q+1,R] [q+1,R] 三个部分,分别表示开头处的零散块,中间的整块与末尾处的零散块。

现在,关键在于快速处理:

  • [ p , q ] [p,q] [p,q] [ p , q ] [p,q] [p,q] 的贡献
    • 跨块的贡献
    • 块内的贡献
  • [ L , p − 1 ] [L,p-1] [L,p1] [ q + 1 , R ] [q+1,R] [q+1,R] 的贡献
  • [ L , p − 1 ] [L,p-1] [L,p1] [ p , q ] [p,q] [p,q] 的贡献
  • [ p , q ] [p,q] [p,q] [ q + 1 , R ] [q+1,R] [q+1,R] 的贡献
  • [ L , p − 1 ] [L,p-1] [L,p1] [ L , p − 1 ] [L,p-1] [L,p1] 的贡献
  • [ q + 1 , R ] [q+1,R] [q+1,R] [ q + 1 , R ] [q+1,R] [q+1,R] 的贡献。

Part 1

先考虑 [ p , q ] [p,q] [p,q] [ p , q ] [p,q] [p,q] 的贡献中跨块的贡献

f i , j f_{i,j} fi,j 表示,第 i i i 个块中 j j j 出现的次数。
g i , j g_{i,j} gi,j 表示, i i i 个块中 j j j 出现的次数。

不难得到这一部分的贡献是

∑ x = c d ∑ i = l r f x , i × ( ( g d , r − g d , i ) − ( g x , r − g x , i ) ) \sum_{x=c}^{d} \sum_{i=l}^r f_{x,i} \times ((g_{d,r}-g_{d,i})-(g_{x,r}-g_{x,i})) x=cdi=lrfx,i×((gd,rgd,i)(gx,rgx,i))

这里 c , d c,d c,d 表示 p p p q q q 所在的块的编号。

考虑展开成四个部分,则原式可以写成下面的四个式子之和。现在关键在于计算下面的四个式子。

Part 1.1

∑ x = c d ∑ i = l r f x , i × g d , r \sum_{x=c}^d \sum_{i=l}^r f_{x,i} \times g_{d,r} x=cdi=lrfx,i×gd,r

显然,随着 x x x i i i 的变化 g d , r g_{d,r} gd,r 不变,于是我们可以将 g d , r g_{d,r} gd,r 提到外面。

我们先预处理,对每一个 f x f_x fx 做前缀和;查询的时候,枚举 x x x O ( 1 ) O(1) O(1) 求出 ∑ x = c d f x , i \sum_{x=c}^d f_{x,i} x=cdfx,i 并累加即可。

Part 1.2

− ∑ x = c d ∑ i = l r f x , i × g d , i -\sum_{x=c}^d \sum_{i=l}^r f_{x,i} \times g_{d,i} x=cdi=lrfx,i×gd,i

交换一下 ∑ \sum

− ∑ i = l r g d , i ∑ x = c d f x , i -\sum_{i=l}^r g_{d,i} \sum_{x=c}^d f_{x,i} i=lrgd,ix=cdfx,i

对于每一个 i i i,预处理出 f x , i f_{x,i} fx,i 的前缀和,查询的时候枚举 i i i O ( 1 ) O(1) O(1) 求出里面的 ∑ \sum ,乘上 g d , i g_{d,i} gd,i 并累加即可。

Part 1.3

− ∑ x = c d ∑ i = l r f x , i × g x , r -\sum_{x=c}^d \sum_{i=l}^r f_{x,i} \times g_{x,r} x=cdi=lrfx,i×gx,r

同理。

Part 1.4

∑ x = c d ∑ i = l r f x , i × g x , i \sum_{x=c}^d \sum_{i=l}^r f_{x,i} \times g_{x,i} x=cdi=lrfx,i×gx,i

维护 p x , i = f x , i × g x , i p_{x,i}=f_{x,i} \times g_{x,i} px,i=fx,i×gx,i 的前缀和即可。


从而,Part 1 可以单次 O ( n ) O(\sqrt n) O(n ) 算出。

Part 2

考虑 [ p , q ] [p,q] [p,q] [ p , q ] [p,q] [p,q] 的贡献中块内部产生的贡献。显然,这一部分中块与块是独立的,这启发我们去预处理。

我们可以对于每一个块,将其内部的 a a a内部离散化并记录两个数组 l i s 1 , l i s 2 lis1,lis2 lis1,lis2。对于一个真实值 i i i,该块内不超过它的最大数即为 l i s 1 i lis1_i lis1i,该块内不小于它的最小数即为 l i s 2 i lis2_i lis2i

离散化后,我们在块内找到每一对正序对,并将它们存储在一个 B × B B \times B B×B 的二维表里面,并将这个表做二维前缀和;注意,表的第 i i i 行第 j j j 列表示满足 a x = i , a y = j a_x=i,a_y=j ax=i,ay=j 的逆序对 ( a x , a y ) (a_x,a_y) (ax,ay) 的数量。查询的时候,枚举块,令 l ′ = l i s 1 l 2 l'=lis1_{l2} l=lis1l2 r ′ = l i s r 2 r'=lis_{r2} r=lisr2,二维矩阵 [ l ′ , r ′ ] [ l ′ , r ′ ] [l',r'][l',r'] [l,r][l,r] 的和即为该块的贡献。

从而,Part 2 单次 O ( n ) O(\sqrt n) O(n ) 求出。

Part 3

我们在 [ l 1 , p − 1 ] [l_1,p-1] [l1,p1] 中枚举一个 a i ( a i ∈ [ l 2 , r 2 ] ) a_i(a_i \in [l_2,r_2]) ai(ai[l2,r2]),然后在 [ q + 1 , r 1 ] [q+1,r_1] [q+1,r1] 所在块中查表得到 l ′ = l i s 1 a i + 1 , r ′ = l i s 2 r 2 l'=lis1_{a_i+1},r'=lis2_{r_2} l=lis1ai+1,r=lis2r2

现在,我们需要求出, [ q + 1 , r 1 ] [q+1,r_1] [q+1,r1] 中存在多少个在 [ l ′ , r ′ ] [l',r'] [l,r] 中的数(注意,已经离散化)。我们对于每个块,对于每个 i i i,预处理一个长度为 B B B 的数组 l i s 3 \color {gold} {lis_3} lis3 表示 i i i 在该块各个位置的出现情况 0 / 1 0/1 0/1,并将其做前缀和,从而每次可以 O ( 1 ) O(1) O(1) 查询。

从而,Part 3 可以在单次 O ( n ) O(\sqrt n) O(n ) 的复杂度内求出。

Part 4

枚举一个 [ l 1 + 1 , p − 1 ] [l_1+1,p-1] [l1+1,p1] 中的数 a i ( a i ∈ [ l 2 , r 2 ] ) a_i(a_i \in [l_2,r_2]) ai(ai[l2,r2]),然后调用 g g g 的前缀和数组即可。

从而,Part 4 可以在单次 O ( n ) O(\sqrt n) O(n ) 的复杂度内求出。

Part 5

与 Part 4 同理,单次 O ( n ) O(\sqrt n) O(n )

Part 6

枚举一个 [ l 1 + 1 , p − 1 ] [l_1+1,p-1] [l1+1,p1] 中的位置 i i i,然后在 l i s 3 \color {gold} {lis_3} lis3 的前缀和数组里面做查询即可。

单次 O ( n ) O(\sqrt n) O(n )

Part 7

与 Part 6 同理。

值得注意的是,本题也需要特判“恰好在一个块内的查询”的情况,且此情况可以采用与 Part 6/7 类似的方法进行单次 O ( n ) O(\sqrt n) O(n ) 的计算。


综上所述,时间复杂度 O ( ( n + q ) n ) O((n+q) \sqrt n) O((n+q)n ),空间复杂度 O ( n n ) O(n \sqrt n) O(nn ),常数非常大。

Summary

我们开了许多大数组,这里有必要对空间进行规划。

  • f f f,空间为 n 2 B \frac {n^2} {B} Bn2
  • g g g,空间为 n 2 B \frac {n^2} {B} Bn2
  • f i , j f_{i,j} fi,j,固定 i i i 时的前缀和,空间为 n 2 B \frac {n^2} {B} Bn2
  • f i , j f_{i,j} fi,j,固定 j j j 时的前缀和,空间为 n 2 B \frac {n^2} {B} Bn2
  • p i , j p_{i,j} pi,j,固定 i i i 时的前缀和,空间为 n 2 B \frac {n^2} {B} Bn2
  • l i s 1 lis1 lis1,空间为 n 2 B \frac {n^2} {B} Bn2
  • l i s 2 lis2 lis2,空间为 n 2 B \frac {n^2} {B} Bn2
  • 每个块内都有一个二维矩阵的前缀和数组,空间为 n B nB nB
  • l i s 3 lis3 lis3 的前缀和,空间为 n B nB nB

7 × n 2 B 7 \times \frac {n^2} {B} 7×Bn2 2 n B 2nB 2nB 十分接近时,空间最优。解方程,不难得到

B = 14 n 2 B=\frac {\sqrt {14n}} {2} B=214n

带入 n = 1 0 5 n=10^5 n=105,空间总和是 236643311 236643311 236643311。由于空间限制是 1GB \text{1GB} 1GB,所以可以通过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值