Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions Algorithm/BinarySearch/atCoder/BinarySearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ func binarySearch(A []int, X int) int {
}

func main() {
var N, X int
fmt.Scan(&N, &X)
A := make([]int, N)
for i := 0; i < N; i++ {
fmt.Scan(&A[i])
}
var N, X int
fmt.Scan(&N, &X)
A := make([]int, N)
for i := 0; i < N; i++ {
fmt.Scan(&A[i])
}

fmt.Println(binarySearch(A, X))
fmt.Println(binarySearch(A, X))
}
78 changes: 78 additions & 0 deletions Mathematics/Prefix Sum/atcoder/B06/B06.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// この問題は、**部分区間の 0/1 の出現回数を高速に数える典型問題**です。
// 各クエリ(`L`, `R`)に対して、アタリ(=1)とハズレ(=0)の数を数え、それを比較すればよいです。
// 高速に処理するために、**累積和(prefix sum)を使ってアタリ(=1)の個数を前計算**しておきましょう。
// ---

// ### ✅ 方針(JavaScript)

// 1. 入力を受け取る(`fs` 使用)
// 2. `N` 個のくじの結果 `A` を受け取る
// 3. 累積和 `acc` を作成(アタリの数の累積)
// 4. 各クエリ `(L, R)` に対して `acc[R] - acc[L - 1]` で区間のアタリ数を計算
// 5. 区間長と比較して出力(`win`/`lose`/`draw`)
// ---

// ### ✅ コード(JavaScript / Node.js, `fs`使用)

const fs = require('fs');

const input = fs.readFileSync('/dev/stdin', 'utf-8').trim().split('\n');
const N = Number(input[0]);
const A = input[1].split(' ').map(Number);
const Q = Number(input[2]);
const queries = input.slice(3).map((line) => line.split(' ').map(Number));

// 累積和(1の個数を数える)
const acc = [0];
for (let i = 0; i < N; i++) {
acc.push(acc[i] + A[i]);
}

// 各クエリに答える
const result = [];
for (const [L, R] of queries) {
const ones = acc[R] - acc[L - 1];
const total = R - L + 1;
const zeros = total - ones;

if (ones > zeros) {
result.push('win');
} else if (zeros > ones) {
result.push('lose');
} else {
result.push('draw');
}
}

console.log(result.join('\n'));

// ### ✅ 実行例

// #### 入力

// ```
// 7
// 0 1 1 0 1 0 0
// 3
// 2 5
// 2 7
// 5 7
// ```

// #### 出力

// ```
// win
// draw
// lose
// ```

// ---

// ### ✅ 計算量・高速性

// * 前処理:O(N)(累積和)
// * 各クエリ:O(1)
// * 全体:O(N + Q) → 最大でも 2 × 10⁵ と高速!

// ---
53 changes: 53 additions & 0 deletions Mathematics/Prefix Sum/atcoder/B06/B06.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from typing import List, Tuple

def solve_lottery_problem(N: int, A: List[int], queries: List[Tuple[int, int]]) -> List[str]:
# 累積和: acc[i] は A[0] から A[i-1] までの 1 の個数
acc: List[int] = [0] * (N + 1)
for i in range(N):
acc[i + 1] = acc[i] + A[i]

results: List[str] = []
for L, R in queries:
ones: int = acc[R] - acc[L - 1]
total: int = R - L + 1
zeros: int = total - ones
if ones > zeros:
results.append("win")
elif zeros > ones:
results.append("lose")
else:
results.append("draw")
return results

def main() -> None:
import sys
input = sys.stdin.read
data = input().split()

N: int = int(data[0])
A: List[int] = list(map(int, data[1:N+1]))
Q: int = int(data[N+1])

queries: List[Tuple[int, int]] = []
index = N + 2
for _ in range(Q):
L: int = int(data[index])
R: int = int(data[index + 1])
queries.append((L, R))
index += 2

results = solve_lottery_problem(N, A, queries)
print('\n'.join(results))

if __name__ == "__main__":
main()

# ✅ 計算量
# 累積和構築: O(N)
# 各クエリ処理: O(1)
# 全体: O(N + Q)

# ✅ まとめ
# 型ヒントで可読性と安全性が向上
# acc(累積和)で高速にクエリ処理
# Python標準の sys.stdin.read() により高速な入力処理対応済み
74 changes: 74 additions & 0 deletions Mathematics/Prefix Sum/atcoder/B06/B06.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// ## ✅ TypeScript 解法(`fs`を使って標準入力を読む)
import * as fs from 'fs';

// 標準入力の読み取り
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');

const N = parseInt(input[0]);
const A = input[1].split(' ').map(Number);
const Q = parseInt(input[2]);
const queries: [number, number][] = input.slice(3).map(line => {
const [L, R] = line.split(' ').map(Number);
return [L, R];
});

// 累積和: acc[i] = A[0] ~ A[i-1] までのアタリ(=1)の数
const acc: number[] = new Array(N + 1).fill(0);
for (let i = 0; i < N; i++) {
acc[i + 1] = acc[i] + A[i];
}

// クエリ処理
const results: string[] = [];
for (const [L, R] of queries) {
const ones = acc[R] - acc[L - 1];
const total = R - L + 1;
const zeros = total - ones;

if (ones > zeros) {
results.push('win');
} else if (ones < zeros) {
results.push('lose');
} else {
results.push('draw');
}
}

// 出力
console.log(results.join('\n'));

// ## ✅ 補足ポイント

// * `acc[i]` は `A[0]` から `A[i - 1]` までのアタリの数(0ベースのため `acc[i+1] = acc[i] + A[i]`)。
// * 各クエリは 1-indexed なので `acc[R] - acc[L - 1]` で区間 `[L, R]` のアタリ数。
// * 出力は `console.log` 一括。

// ## ✅ 入力例と出力(確認)

// ### 入力

// ```
// 7
// 0 1 1 0 1 0 0
// 3
// 2 5
// 2 7
// 5 7
// ```

// ### 出力

// ```
// win
// draw
// lose
// ```

// ---

// このコードは **最大 10⁵ 件のクエリに対しても高速に処理**できます。
// Node.js で TypeScript を実行するには `ts-node` を使うのが便利です。

// ```bash
// npx ts-node solution.ts < input.txt
// ```
154 changes: 154 additions & 0 deletions Mathematics/Prefix Sum/atcoder/B06/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@

---

## 🧩 問題概要(図で説明)

太郎くんが引いたくじの結果(`A`)があります:

```
A = [0, 1, 1, 0, 1, 0, 0]
↑ ↑ ↑ ↑ ↑ ↑
1 2 3 6 7
```

これに対して、たとえば次のような\*\*クエリ(質問)\*\*が来ます:

* 「2 回目から 5 回目まで、当たり(1)とハズレ(0)どっちが多い?」
* 「5 回目から 7 回目まででは?」

このような「区間 `[L, R]` における当たりとハズレの数を比較せよ」という問題を **高速に答える必要があります(最大10万件)**。

---

## 🔍 処理の流れと図解

---

### ① 入力の受け取り

```ts
const N = parseInt(input[0]);
const A = input[1].split(' ').map(Number);
```

入力 `A` の例:

```
A = [0, 1, 1, 0, 1, 0, 0]
↑ ↑ ↑ ↑ ↑ ↑ ↑
1 2 3 4 5 6 7 ← index(1-indexed)
```

---

### ② 累積和 `acc` の構築

```ts
const acc: number[] = new Array(N + 1).fill(0);
for (let i = 0; i < N; i++) {
acc[i + 1] = acc[i] + A[i];
}
```

**目的:`acc[i] = A[0] ~ A[i-1] までのアタリ(=1)の累積和` を持つ**

| i (1-indexed) | A\[i-1] | acc\[i] | 解釈 |
| ------------- | ------- | ------- | --------------------------------- |
| 0 | - | 0 | 初期値 |
| 1 | 0 | 0 | A\[0] = 0 |
| 2 | 1 | 1 | A\[0]+A\[1] = 0+1 |
| 3 | 1 | 2 | A\[0]+A\[1]+A\[2] = 0+1+1 |
| 4 | 0 | 2 | A\[0]+A\[1]+A\[2]+A\[3] = 0+1+1+0 |
| 5 | 1 | 3 | … |
| 6 | 0 | 3 | … |
| 7 | 0 | 3 | … |

```txt
acc = [0, 0, 1, 2, 2, 3, 3, 3]
↑ ↑ ↑ ↑ ↑ ↑ ↑
1 2 3 4 5 6 7(1-indexed)
```

---

### ③ クエリ処理(各クエリで何をしているか?)

たとえばクエリが `L=2`, `R=5` のとき:

```ts
const ones = acc[R] - acc[L - 1]; // acc[5] - acc[1] = 3 - 0 = 3
const total = R - L + 1; // 5 - 2 + 1 = 4
const zeros = total - ones; // 4 - 3 = 1
```

#### 🎯 区間 `[2,5]` の様子:

```
A = [0, 1, 1, 0, 1, 0, 0]
↑ ↑ ↑ ↑ ← index = 2〜5
1 1 0 1 → アタリ3個、ハズレ1個 → win!
```

同様に、

#### クエリ `[5,7]`

```
A = [0, 1, 1, 0, 1, 0, 0]
↑ ↑ ↑
5 6 7 → 1, 0, 0 → アタリ1, ハズレ2 → lose!
```

---

### ④ 結果出力

```ts
if (ones > zeros) results.push('win');
else if (zeros > ones) results.push('lose');
else results.push('draw');
```

---

## ✅ 全体図のまとめ

```txt
入力
└── A = [0, 1, 1, 0, 1, 0, 0]
↓ 累積和 acc[i] = A[0]~A[i-1]の1の数
acc = [0, 0, 1, 2, 2, 3, 3, 3]

クエリ処理(例: [2,5])
ones = acc[5] - acc[1] = 3 - 0 = 3
total = 5 - 2 + 1 = 4
zeros = 4 - 3 = 1
→ アタリの方が多い → win
```

---

## ⏱ 計算量のイメージ

| 処理 | 回数 | 計算量 |
| -------- | -- | ------------------------ |
| 累積和の構築 | N回 | O(N) |
| クエリごとの処理 | Q回 | O(1) × Q |
| 合計 | | **O(N + Q)**(最大20万でも余裕!) |

---

## 🧠 まとめ

* 累積和(prefix sum)を使って高速に区間の「当たりの数」を数える
* ハズレの数は「区間の長さ − アタリの数」で計算
* クエリごとに「win / lose / draw」を即時判定
* 典型的な **二値配列への累積和適用パターン**

---

| [提出日時](https://atcoder.jp/contests/tessoku-book/submissions/me?desc=true&orderBy=created) | 問題 | ユーザ | 言語 | [得点](https://atcoder.jp/contests/tessoku-book/submissions/me?desc=true&orderBy=score) | [コード長](https://atcoder.jp/contests/tessoku-book/submissions/me?orderBy=source_length) | 結果 | [実行時間](https://atcoder.jp/contests/tessoku-book/submissions/me?orderBy=time_consumption) | [メモリ](https://atcoder.jp/contests/tessoku-book/submissions/me?orderBy=memory_consumption) | |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 2025-07-02 19:26:36 | [B06 - Lottery](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_ce) | [myoshizumi](https://atcoder.jp/users/myoshizumi) | [Python (CPython 3.11.4)](https://atcoder.jp/contests/tessoku-book/submissions/me?f.Language=5055) | 1000 | 1200 Byte | | 109 ms | 43780 KiB | [詳細](https://atcoder.jp/contests/tessoku-book/submissions/67238676) |
| 2025-07-02 19:14:56 | [B06 - Lottery](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_ce) | [myoshizumi](https://atcoder.jp/users/myoshizumi) | [TypeScript 5.1 (Node.js 18.16.1)](https://atcoder.jp/contests/tessoku-book/submissions/me?f.Language=5058) | 1000 | 977 Byte | | 146 ms | 85980 KiB | [詳細](https://atcoder.jp/contests/tessoku-book/submissions/67238307) |
| 2025-07-02 19:08:01 | [B06 - Lottery](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_ce) | [myoshizumi](https://atcoder.jp/users/myoshizumi) | [JavaScript (Node.js 18.16.1)](https://atcoder.jp/contests/tessoku-book/submissions/me?f.Language=5009) | 1000 | 798 Byte | | 140 ms | 87404 KiB | [詳細](https://atcoder.jp/contests/tessoku-book/submissions/67238111) |