1. [1..3] of [1,2,3,4,5] -> 9
  2. single element range
  3. whole array
  4. from start
  5. to end
  6. with negatives
コース一覧
コンピューターサイエンス入門:理論編
累積和で範囲合計

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

累積和で範囲合計

累積和で区間を一発で出す

同じ範囲を、何度も足し直している

売上が日ごとに 365 件並んでいるとします。「4 月分の合計は」「5 月から 7 月は」「今年の前半は」と聞かれるたびに、その範囲を頭から足していくと、1 回の質問につき最大 365 回の足し算です。質問が 1000 回来れば、36 万回になります。

けれど、足しているのはいつも同じ数字たちです。何度も足し直すのではなく、先に 1 回だけ足しておいて、あとは引き算で取り出す ことができます。

Python

print(365 * 1000) # 毎回足し直すと 36 万 5000 回 print(365 + 1000) # 先に累計を作れば 1365 回

下ごしらえが 365 回、質問は 1 回あたり数回。質問が増えるほど差が開きます。

電気メーターは、毎月ゼロに戻らない

この仕組みは、電気のメーターとまったく同じです。メーターは使い始めからの累計を表示し続け、毎月ゼロには戻りません。だから今月の使用量は、今月の指針から先月の指針を引くだけで出ます。

Python

# 検針 0 回目から 4 回目までの、累計の指針 meter = [0, 120, 265, 380, 510] # 2 回目と 3 回目の 2 か月ぶん print(meter[3] - meter[1]) # 260

265 - 120 = 145 と 380 - 265 = 115 を足しても 260 です。途中の月をいちいち足さなくても、両端の 2 つを引けば答えが出ます。累計を持っておくというのは、こういうことです。

先頭に 0 を 1 つ置いておく

メーターの一覧の先頭に 0 が入っているのは、飾りではありません。「まだ 1 回も使っていない状態」を表す、れっきとした 1 件です。

これが無いと、いちばん最初の期間だけ引く相手がいなくなり、そこだけ特別扱いのコードを書く羽目になります。先頭に 0 を置いておけば、最初の期間も他とまったく同じ形の引き算で求められます。だから累計の一覧は、元のデータより 1 つ長く なります。ここを同じ長さで作ってしまうと、最後の期間を取り出すときに範囲の外へ手が伸びます。

どこからどこまでか、を先に決める

累積和でいちばん間違えるのは、足し算ではなく 端の扱い です。

Python

days = [10, 20, 30, 40, 50] print(days[1:3]) # [20, 30] 3 番目は入らない print(days[1:4]) # [20, 30, 40]

「3 番目から 5 番目まで」と言ったとき、5 番目を含むのか含まないのかで、引く相手が 1 つずれます。含む約束と含まない約束では、正しい式が別物になります。どちらで書かれた仕様なのかを先に読み、小さなデータで手計算して答え合わせをしてから、本番のデータに通してください。

解説

累積和は「あとで何度も聞かれるなら、先に払っておく」という考え方の入口です。データベースのインデックスや集計テーブルも、根っこは同じ発想です。

要件

  1. 累積和 prefix を一度作り、prefix[r+1] - prefix[l] で範囲合計を求めること
  2. 0 <= l <= r < len(arr) を前提として良い
  3. 戻り値は整数 (int)

入出力例

rangeSum([1,2,3,4,5], 1, 3) → 9 rangeSum([1,2,3,4,5], 2, 2) → 3 rangeSum([1,2,3,4,5], 0, 4) → 15 rangeSum([10,20,30,40], 0, 2) → 60 rangeSum([10,20,30,40], 2, 3) → 70 rangeSum([-1,2,-3,4,-5], 1, 3) → 3

ヒント

prefix の長さは n + 1。prefix[0] = 0 から始めて prefix[i+1] = prefix[i] + arr[i] で埋める

範囲 [l, r] (両端含む) の合計は prefix[r+1] - prefix[l]

1 回のクエリだけなら累積和を作る意味は薄いが、複数回のクエリで O(1) になるのが本来の利点

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 第3章まとめクイズ

    計算量と Big-O、線形探索・二分探索・累積和の理解度を 1 問のクイズで確認する。

  • スタック (push/pop) を実装する

    後入れ先出し (LIFO) の代表選手であるスタックを、push と pop の操作シーケンスで動かす。

  • バイト → KB 変換

    1024 で割って KB に変換し、容量表示の基本を体得する

  • Base64 エンコード後の長さ計算

    バイト列を Base64 エンコードしたときの文字数を、入力長から数式で求める関数を作ります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • データベースデータを構造化して保存する仕組み
  • インデックスDB 検索を速くする索引
  • テーブルDB の表 (Excel のシートみたいなもの)
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

累積和で範囲合計

⌘S で保存