M - 等しい数 / Equal Queries Editorial by noimi
平方分割による別解を紹介します。 こちらの方が実装は楽かもしれません。
要素 \(i\) の数列の中での頻度を \(C_i\) と置くと求める答えは \(\displaystyle\sum \dfrac{C_i \times (C_i - 1)}{2} \) です。
クエリの処理で \(C_i\) の増減を見れば、差分を管理することで答えが求まります。 数列を長さ \(B\) のブロック \(\dfrac{N}{B}\) 個に分割します。クエリ \([l, r]\) に対して、
A: 完全に内包されているブロック
ブロック内の要素がすべて同じ場合
- \(O\left(1\right)\) で処理することができます。
そうでない場合
- \(O\left(B\right)\) で処理し、ブロック内の要素がすべて同じになったというフラグを立てます。
B: 一部だけ重なっているブロック
- \(O\left(B\right)\) で処理し、ブロック内の要素がすべて同じというフラグを外します。
A で \(O\left(B\right)\) で処理する必要のあるブロックはクエリ毎で高々二つしか増えず、一度 \(O\left(B\right)\) で処理すると B で引っかかるまでは \(O\left(1\right)\) で処理できることから、全体で \(O\left(N + QB + QN/B\right)\) で解くことができます。
\(B = \sqrt{N}\) とすることで、\(O\left(N + Q\sqrt{N}\right)\) が達成可能です。
posted:
last update: