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
i≤j
②
p
i
≤
p
j
p_i \le p_j
pi≤pj
③
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 1≤n,q≤105,时限 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,p−1], [ 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,p−1] 对 [ q + 1 , R ] [q+1,R] [q+1,R] 的贡献
- [ L , p − 1 ] [L,p-1] [L,p−1] 对 [ 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,p−1] 对 [ L , p − 1 ] [L,p-1] [L,p−1] 的贡献
- [ 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=c∑di=l∑rfx,i×((gd,r−gd,i)−(gx,r−gx,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=c∑di=l∑rfx,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=c∑di=l∑rfx,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=l∑rgd,ix=c∑dfx,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=c∑di=l∑rfx,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=c∑di=l∑rfx,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,p−1] 中枚举一个 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,p−1] 中的数 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,p−1] 中的位置 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,所以可以通过。