Unverified Commit 9623c074 authored by Angel_Kitty's avatar Angel_Kitty Committed by GitHub
Browse files

Merge pull request #1906 from MicDZ/patch-3

Update mo-algo.md
parents e974a8e1 0b7f9463
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ void solve() {

以下的情况在 $n$ 和 $m$ 同阶的前提下讨论。

首先是分块这一步,这一步的时间复杂度毫无疑问地是 $O(\sqrt{n}\cdot\sqrt{n}\log\sqrt{n}+n\log n)=O(n\log n)$ ;
首先是分块这一步,这一步的时间复杂度是 $O(\sqrt{n}\cdot\sqrt{n}\log\sqrt{n}+n\log n)=O(n\log n)$ ;

接着就到了莫队算法的精髓了,下面我们用通俗易懂的初中方法来证明它的时间复杂度是 $O(n\sqrt{n})$ ;

@@ -100,7 +100,7 @@ $$

对于区间 $[i,i]$ ,由于区间只有一个元素,我们很容易就能知道答案。然后一步一步从当前区间(已知答案)向下一个区间靠近。

我们设 $col[i]$ 表示当前颜色 i 出现了多少次, $ans$ 当前共有多少种可行的配对方案(有多少种可以选到一双颜色相同的袜子),表示然后每次移动的时候更新答案——设当前颜色为 $k$ ,如果是增长区间就是 $ans$ 加上 $C_{col[k]+1}^2-C_{col[k]}^2$ ,如果是缩短就是 $ans$ 减去 $C_{col[k]}^2-C_{col[k]-1}^2$ 。这应该很好理解。
我们设 $col[i]$ 表示当前颜色 $i$ 出现了多少次, $ans$ 当前共有多少种可行的配对方案(有多少种可以选到一双颜色相同的袜子),表示然后每次移动的时候更新答案——设当前颜色为 $k$ ,如果是增长区间就是 $ans$ 加上 $C_{col[k]+1}^2-C_{col[k]}^2$ ,如果是缩短就是 $ans$ 减去 $C_{col[k]}^2-C_{col[k]-1}^2$ 。

而这个询问的答案就是 $\displaystyle \frac{ans}{C_{r-l+1}^2}$ 。

@@ -110,11 +110,6 @@ $$

所以 $C_{col[k]+1}^2-C_{col[k]}^2=col[k]$ 。

这样我们少算了很多东西呢!
至少我的代码在 BZOJ 上测快了一倍。

还有,算 $C_a^2$ 可以用位运算, `a/2` 可以写成 `a>>1`

算法总复杂度: $O(n\sqrt{n} )$ 

下面的代码中 `mot` 表示答案的分母 (mother), `sub` 表示分子, `sqn` 表示块的大小: $\sqrt{n}$ , `arr` 是输入的数组, `node` 是存储询问的结构体, `tab` 是询问序列(排序后的), `col` 同上所述。