赛时我使用了 bitset 代替 bool 数组,bitset 是个标准库中的容器,在 \(64\) 位操作系统大将一个 \(64\) 位整数的每一位当作一个 bool 变量,所以储存空间拥有 \(\frac{1}{8}\) 的常数,做很多常见操作,如给两个 bool 数组的相同的下标上的元素求 & 时拥有 \(\frac{1}{64}\) 的常数。为了用 \(O\) 标记表现 bitset 带来的优化,同时也为了表现操作系统位数对优化的差异,我们设 \(w\) 为操作系统位数,若使用 bitset 优化本算法,时间复杂度则为 \(O(\frac{n^2+nm}{w})\)。
我会在本题的代码的解释中解释 bitset 对应的操作的作用,若对 bitset 支持的更多操作感兴趣可以前往 OI-Wiki 学习更多用法。
[code]#include #include using namespace std;using ll = long long;constexpr int N = 2000 + 1, M = 50000 + 1;int mid[N][N];bitset um[N], uvm[M];int main() { int n, m; cin >> n >> m; int tot = 0; for (int i = 1; i > u >> v >> w; int &nid = mid[v];//(u, v) 二元组对应的编号 if (!nid) {//如果之前没有编号过 nid = ++tot;//新建编号 } um[v] = true; uvm[nid][w] = true; } ll ans = 0; for (int a = 1; a < n; ++a) { auto &uma = um[a]; for (int b = uma._Find_next(a)/*_Find_next(x)函数:找到 bitset 中 x 下标后的第一个 true 的位置*/; b