累積和
競プロで知ったことのメモ。
簡単な概要
累積和とは前処理をすればの計算量で、区間の合計を求めることができるアルゴリズム。
例えば、長さの数字の配列があるとする。
2 | 6 | 1 | 9 | 5 | 8 | 4 |
から までの区間の合計を求めたいというときは、単純にからまでをループ()すれば求めることができる。
配列が長かったり、~ 、~ 、~ .....と区間の合計を求める回数が例えば回もある場合、かかるので処理にとても時間がかかってしまう。
累積和を使うと前処理にかければ、区間の合計を求める計算量はで済む。
どんな前処理かというと、以下のような大きい配列を用意する。
0 | 2 | 8 | 9 | 18 | 23 | 31 | 35 |
この配列の中身、にはまでの区間の合計が入っている。
- ...
- ...
- ...
この配列を用意すれば、から までの区間の合計はという式で求めることができる。
にはからの合計が入っているので、からの合計が入っているを引く。
となる。
実装
上の例、から までの区間の合計を求めるプログラムをC#で実装してみる。
void Sample() { var N = 7; var a = new int[7] { 2, 6, 1, 9, 5, 8, 4 }; var s = new int[N + 1]; var left = 2; var right = 6; for (int i = 0; i < N; i++) { s[i + 1] = s[i] + a[i]; } Console.WriteLine(s[right + 1] - s[left]); }