### 与莫队结合
-详见 [杂项/莫队配合bitset](../../misc/mo-algo-with-bitset.md) 。
+详见 [杂项/莫队配合 bitset](../../misc/mo-algo-with-bitset.md) 。
### 计算高维偏序
dfs 一棵树,然后如果 dfs 到 x 点,就 `push_back(x)` ,dfs 完 x 点,就直接 `push_back(-x)` ,然后我们在挪动指针的时候,
-- 新加入的值是 x ---> `add(x)`
-- 新加入的值是 - x ---> `del(x)`
-- 新删除的值是 x ---> `del(x)`
-- 新删除的值是 - x ---> `add(x)`
+- 新加入的值是 x ---> `add(x)`
+- 新加入的值是 - x ---> `del(x)`
+- 新删除的值是 x ---> `del(x)`
+- 新删除的值是 - x ---> `add(x)`
这样的话,我们就把一棵树处理成了序列。
其中:$val$ 表示该颜色的价值,$cnt$ 表示颜色出现的次数,$w$ 表示该颜色出现 $i$ 次后的价值
-先把树变成序列,然后每次添加/删除一个点,这个点的对答案的的贡献是可以在 $O(1)$ 时间内获得的,即 $val_c\times w_{cnt_{c+1}}$
+先把树变成序列,然后每次添加/删除一个点,这个点的对答案的的贡献是可以在 $O(1)$ 时间内获得的,即 $val_c\times w_{cnt_{c+1}}$
发现因为他会把起点的子树也扫了一遍,产生多余的贡献,怎么办呢?
#include <cmath>
#include <cstdio>
#include <iostream>
+ ```
#define DEBUG printf("line:%d func:%s\n", __LINE__, __FUNCTION__);
bitset 常用于常规数据结构难以维护的的判定、统计问题,而莫队可以维护常规数据结构难以维护的区间信息。把两者结合起来使用可以同时利用两者的优势。
-## 例题 [「Ynoi2016」掉进兔子洞](https://www.luogu.com.cn/problem/P4688)
+## 例题 [「Ynoi2016」掉进兔子洞](https://www.luogu.com.cn/problem/P4688)
本题刚好符合上面提到的莫队配合 bitset 的特征。不难想到我们可以分别用 bitset 存储每一个区间内的出现过的所有权值,一组询问的答案即所有区间的长度和减去三者的并集元素个数 $\times 3$ 。
## 习题
-- [小清新人渣的本愿](https://www.luogu.com.cn/problem/P3674)
-- [「Ynoi2017」由乃的玉米田](https://www.luogu.com.cn/problem/P5355)
-- [「Ynoi2011」WBLT](https://www.luogu.com.cn/problem/P5313)
+- [小清新人渣的本愿](https://www.luogu.com.cn/problem/P3674)
+- [「Ynoi2017」由乃的玉米田](https://www.luogu.com.cn/problem/P5355)
+- [「Ynoi2011」WBLT](https://www.luogu.com.cn/problem/P5313)
所以 $C_{col[k]+1}^2-C_{col[k]}^2=col[k]$ 。
-算法总复杂度: $O(n\sqrt{n} )$
+算法总复杂度: $O(n\sqrt{n} )$
下面的代码中 `deno` 表示答案的分母 (denominator), `nume` 表示分子(numerator), `sqn` 表示块的大小: $\sqrt{n}$ , `arr` 是输入的数组, `node` 是存储询问的结构体, `tab` 是询问序列(排序后的), `col` 同上所述。
- **注意:由于 `++l` 和 `--r` 的存在,下面代码中的移动区间的 4 个 for 循环的位置很关键,不能改变它们之间的位置关系。**
+ **注意:由于 `++l` 和 `--r` 的存在,下面代码中的移动区间的 4 个 for 循环的位置很关键,不能改变它们之间的位置关系。**
??? 参考代码
```cpp
## 参考资料
-- [莫队算法学习笔记 | Sengxian's Blog](https://blog.sengxian.com/algorithms/mo-s-algorithm)
\ No newline at end of file
+- [莫队算法学习笔记 | Sengxian's Blog](https://blog.sengxian.com/algorithms/mo-s-algorithm)
那么我们的坐标也可以在时间维上移动,即 $[l,r,time]$ 多了一维可以移动的方向,可以变成:
-- $[l-1,r,time]$
-- $[l+1,r,time]$
-- $[l,r-1,time]$
-- $[l,r+1,time]$
-- $[l,r,time-1]$
-- $[l,r,time+1]$
+- $[l-1,r,time]$
+- $[l+1,r,time]$
+- $[l,r-1,time]$
+- $[l,r+1,time]$
+- $[l,r,time-1]$
+- $[l,r,time+1]$
这样的转移也是 $O(1)$ 的,但是我们排序又多了一个关键字,再搞搞就行了。
回滚莫队分为只使用增加操作的回滚莫队和只使用删除操作的回滚莫队。以下仅介绍只使用增加操作的回滚莫队,只使用删除操作的回滚莫队和只使用增加操作的回滚莫队只在算法实现上有一点区别,故不再赘述。
-## 例题 [JOISC 2014 Day1 历史研究](https://loj.ac/problem/2874)
+## 例题 [JOISC 2014 Day1 历史研究](https://loj.ac/problem/2874)
给你一个长度为 $n$ 的数组 $A$ 和 $m$ 个询问 $(1 \leq n, m \leq 10^5)$ ,每次询问一个区间 $[L, R]$ 内重要度最大的数字,要求 **输出其重要度** 。一个数字 $i$ 重要度的定义为 $i$ 乘上 $i$ 在区间内出现的次数。
```cpp
#include <bits/stdc++.h>
using namespace std;
+ ```
typedef long long ll;
const int N = 1e5 + 5;
## 参考资料
-- [回滚莫队及其简单运用 | Parsnip's Blog](https://www.cnblogs.com/Parsnip/p/10969989.html)
+- [回滚莫队及其简单运用 | Parsnip's Blog](https://www.cnblogs.com/Parsnip/p/10969989.html)