打完比赛之后在比赛公告的评论区发现了一种分块思路。
我一看,数据结构题诶。
但是不会做。
写了个分块 + bitset 上去成功 TLE 飞。
如前文所说,在评论区发现了这样一种思路:
设 \(sum_{i,j}\) 表示 \(b\) 的第 \(i\) 块与 \(a\) 的前 \(j\) 块有多少个数相同。
设 \(place_{a,i}\) 表示 \(i\) 在 \(a\) 中的编号,设 \(place_{b,i}\) 表示 \(i\) 在 \(b\) 中的编号。
然后查询我们先处理 \(b\) 的完整块,
我们用 \(sum\) 数组计算 \(a\) 的完整块对 \(b\) 的完整块的答案贡献,
再用 \(place_b\) 计算 \(a\) 的角块对 \(b\) 的完整块的答案贡献。
接着处理 \(b\) 的角块,这个就用 \(place_a\) 计算答案的贡献。
由于 \(sum\) 数组第二维是前缀和,所以我们能以修改从 \(O(1)\) 退化成 \(O(\sqrt{n})\) 的代价,保证查询的复杂度为 \(O(\sqrt{n})\) 而没有退化成 \(O(n)\)。
代码:
1 |
|