数列分块及莫队算法分块大小详解

数列分块及莫队算法分块大小详解

  • 一. 前言
  • 二. 数列分块
  • 三. 普通莫队
  • 四. 带修莫队

一. 前言

众所周知,数列分块和莫队是非常优雅的暴力算法。

那么,我们如何分才能使时间复杂度最优呢?

请看以下证明。

二. 数列分块

数列分块的最佳大小为 n \sqrt{n} n

n n n m m m 同一数量级。

设块长为 s s s , 序列长度 n n n 那么块的总数为 n s \frac{n}{s} sn,每次操作时间复杂度为 O ( n ⋅ s ) O(n⋅s) O(ns)

= s ⋅ n s ⋅ s =s⋅\frac{n}{s}⋅s =ssns

= s 2 ⋅ n s =s^2⋅\frac{n}{s} =s2sn

我们要使该数尽量小,根据小学二年级的数学知识可得:

当且仅当 n s = s \frac{n}{s}=s sn=s时, s 2 ⋅ n s s^2⋅\frac{n}{s} s2sn最小,可得 s 2 = n s^2=n s2=n s = n s=\sqrt n s=n

三. 普通莫队

普通莫队的最佳大小为 n \sqrt{n} n

我们不妨设块的大小为 s s s ,每个块的询问次数为 q i q_i qi ,序列长度为 n n n ,询问总次数为 m m m 。那么块的总数就是 n s \frac{n}{s} sn ,对于块 i i i 来说,其复杂度为 q i ⋅ s + n q_i⋅s+n qis+n
那么总复杂度为 ∑ i = 1 n / s q i ⋅ s + n = m s + n ⋅ n s \sum_{i=1}^{n/s} q_i\cdot s+n=ms+n\cdot \frac{n}{s} i=1n/sqis+n=ms+nsn。因为一般 n n n m m m 都是等数量级的,我们可以大致忽略其大小差异,所以总复杂度变为 n ⋅ s + n 2 ⋅ 1 s n\cdot s+n^2\cdot \frac{1}{s} ns+n2s1
利用基本不等式可得当 n ⋅ s = n 2 ⋅ 1 s n\cdot s=n^2\cdot \frac{1}{s} ns=n2s1 s = n s=\sqrt n s=n 时,原式有最小值 n \sqrt n n

四. 带修莫队

带修莫队最佳大小为 n 2 3 n^\frac{2}{3} n32

n = m n=m n=m ,则有 n ⋅ s + n 3 s 2 ≥ n 4 s n\cdot s+\frac{n^3}{s^2}\geq \sqrt{\frac{n^4}{s}} ns+s2n3sn4 ,当且仅当 n ⋅ s = n 3 s 2 ⇒ s = n 2 3 n\cdot s=\frac{n^3}{s^2}\Rightarrow s=n^{\frac{2}{3}} ns=s2n3s=n32时相等。此时 n 4 s = n 10 3 = n 5 3 \sqrt{\frac{n^4}{s}}=\sqrt{n^{\frac{10}{3}}}=n^{\frac{5}{3}} sn4 =n310 =n35

你可能感兴趣的:(C++,数据结构,C++算法,数据结构,关键字,算法,数据结构)