次にしゃくとり法です。初期値を含め、探索を以下の状態から開始します。
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
lr |
|
|
|
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
l はで、r はで位置を動かしていきます。この時点ではを過ぎ、の直前の所にいます。
r = 1, len_A = 10
for l in range(1, len_A+1):
# >>> いまココ <<<
while r <= len_A and cum_sum[r] - cum_sum[l-1] <= 15:
r += 1
r <= len_A は、r が数列の中にいる間、ループします。
cum_sum[r] - cum_sum[l-1] <= 15 が、累積和で区間和を求めている所です。
数列A の先頭は、cum_sum の要素番号 1 なので、初期値は l = 1, r = 1 です。
cum_sum[1] - cum_sum[0] <= 15
↓
1 - 0 <= 15 … True
となり、True の間は r += 1 だけが実行されます。
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
lr |
|
|
|
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
1 - 0 = 1 … True
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
l |
r |
|
|
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
6 - 0 = 6 … True
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
l |
|
r |
|
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
15 - 0 = 15 … ギリ True
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
l |
|
|
r |
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
16 - 0 = 16 … False
15 以下ではなくなったのでここで False となり、文を抜けます。
ここで l と r の範囲が示す 数列A を見てみます。(下記)
15 以下ではなくなった所が cum_sum の要素番号 4 です。ということは、15 以下の範囲は 数列A の 1 ~ 3 番目です。
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
これを踏まえて次は 15 以下の区間の個数を数えます。
cnt += r - l
if l == r:
r += 1
現在、cnt = 0, l = 1, r = 4 となっています。
4 - 1 = 3 なので、cnt には 3 が加算されます。(現在 cnt = 3)
この 3 は 15 以下の区間の数ですが、その区間というのは次の3つです。
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[1]
[1, 5]
[1, 5, 9]
l == r ではないので次のループに移ります。
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
l |
|
r |
|
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
16 - 1 = 15 … True
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
l |
|
|
r |
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
36 - 1 = 25 … False
cnt += 5 - 2 = 3 (現在 cnt = 6)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[5]
[5, 9]
[5, 9, 1]
↓
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
l |
|
r |
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
36 - 6 = 30 … False
cnt += 5 - 3 = 2 (現在 cnt = 8)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[9]
[9, 1]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
l |
r |
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
36 - 15 = 21 … False
cnt += 5 - 4 = 1 (現在 cnt = 9)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[1]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
lr |
|
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
36 - 16 = 20 … False
cnt += 5 - 5 = 0 (現在 cnt = 9) うまくできてるね…(感心)
l == r なので r += 1 する。
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
lr |
|
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
41 - 36 = 5 … True
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
l |
r |
|
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
44 - 36 = 8 … True
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
l |
|
r |
|
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
50 - 36 = 14 … True
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
l |
|
|
r |
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
55 - 36 = 19 … False
cnt += 9 - 6 = 3 (現在 cnt = 12)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[5]
[5, 3]
[5, 3, 6]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
|
l |
|
r |
|
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
55 - 41 = 13 … True
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
|
l |
|
|
r |
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
59 - 41 = 18 … False
cnt += 10 - 7 = 3 (現在 cnt = 15)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[3]
[3, 6]
[3, 6, 5]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| l, r |
|
|
|
|
|
|
|
|
l |
|
r |
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
59 - 44 = 14 … True
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
| l, r |
|
|
|
|
|
|
|
|
l |
|
|
r |
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
|
r が数列を超えたので False
cnt += 11 - 8 = 3 (現在 cnt = 18)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[6]
[6, 5]
[6, 5, 4]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
| l, r |
|
|
|
|
|
|
|
|
|
l |
|
r |
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
|
r が数列を超えているので False
cnt += 11 - 9 = 2 (現在 cnt = 20)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[5]
[5, 4]
| 要素番号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
| l, r |
|
|
|
|
|
|
|
|
|
|
l |
r |
| cum_sum |
0 |
1 |
6 |
15 |
16 |
36 |
41 |
44 |
50 |
55 |
59 |
|
r が数列を超えているので False
cnt += 11 - 10 = 1 (現在 cnt = 21)
A = [1, 5, 9, 1, 20, 5, 3, 6, 5, 4]
[4]
ここでループが終了し、最後に cnt を画面に出力して完了です。
カウントした分の範囲をかき集めてみると、きちんと 21個あります。
1: [1]
2: [1, 5]
3: [1, 5, 9]
4: [5]
5: [5, 9]
6: [5, 9, 1]
7: [9]
8: [9, 1]
9: [1]
10: [5]
11: [5, 3]
12: [5, 3, 6]
13: [3]
14: [3, 6]
15: [3, 6, 5]
16: [6]
17: [6, 5]
18: [6, 5, 4]
19: [5]
20: [5, 4]
21: [4]