Skip to content

Commit 7b56293

Browse files
committed
fix
1 parent 13d5bb4 commit 7b56293

31 files changed

+547
-687
lines changed

code/main.py

Lines changed: 252 additions & 339 deletions
Large diffs are not rendered by default.

libs/array_create.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
# 多次元配列作成
2-
from typing import List, Any
2+
from typing import Any
33

44

5-
def create_array1(n: int, default: Any = 0) -> List[Any]:
6-
"""
7-
1次元配列を初期化する関数
8-
"""
5+
def create_array1(n: int, default=0) -> list[Any]:
6+
"""1次元配列を初期化する関数"""
97
return [default] * n
108

119

12-
def create_array2(a: int, b: int, default: Any = 0) -> List[List[Any]]:
13-
"""
14-
2次元配列を初期化する関数
15-
"""
10+
def create_array2(a: int, b: int, default=0) -> list[list[Any]]:
11+
"""2次元配列を初期化する関数"""
1612
return [[default] * b for _ in [0] * a]
1713

1814

19-
def create_array3(a: int, b: int, c: int, default: Any = 0) -> List[List[List[Any]]]:
20-
"""
21-
3次元配列を初期化する関数
22-
"""
15+
def create_array3(a: int, b: int, c: int, default=0) -> list[list[list[Any]]]:
16+
"""3次元配列を初期化する関数"""
2317
return [[[default] * c for _ in [0] * b] for _ in [0] * a]

libs/binary_search.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
from typing import Callable
1+
from typing.abc import Callable
22

33

44
def binary_search(
5-
fn: Callable[[int], bool], right: int = 0, left: int = -1, return_left: bool = True
5+
fn: Callable[[int], bool],
6+
right: int = 0,
7+
left: int = -1,
8+
return_left: bool = True,
69
) -> int:
7-
"""
8-
二分探索の抽象的なライブラリ
10+
"""二分探索の抽象的なライブラリ
11+
912
評価関数の結果に応じて、二分探索する
1013
最終的にはleftを出力します
1114

libs/coordinate_compression.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,27 @@
1-
from typing import List, Tuple
1+
def compress_1d(points: list[int] | tuple[int]) -> list[int]:
2+
"""一次元座標圧縮
23
3-
4-
def compress_1d(points: List[int] | Tuple[int]) -> List[int]:
5-
"""
6-
一次元座標圧縮します
74
計算量は、O(N log N)です
85
96
lとrは、まとめて入れる事で、座圧できます
107
"""
11-
res = []
128
d = {num: ind for ind, num in enumerate(sorted(set(points)))}
139

14-
for a in points:
15-
res.append(d[a])
10+
return [d[a] for a in points]
1611

17-
return res
1812

13+
def compress_2d(points) -> list[tuple[int, int]]:
14+
"""二次元座標圧縮
1915
20-
def compress_2d(points):
21-
"""
22-
2次元座標圧縮を行う関数
2316
入力: points - [(x1, y1), (x2, y2), ...] の形式の座標リスト
2417
出力: 圧縮後の座標リストと、元の座標から圧縮後の座標へのマッピング
2518
"""
2619
# x座標とy座標を分離
27-
x_coords = sorted(set(x for x, y in points)) # 重複を削除してソート
28-
y_coords = sorted(set(y for x, y in points))
20+
x_coords = sorted({x for x, y in points}) # 重複を削除してソート
21+
y_coords = sorted({y for x, y in points})
2922

3023
# 座標から圧縮後の値へのマッピング辞書を作成
3124
x_map = {val: idx for idx, val in enumerate(x_coords)}
3225
y_map = {val: idx for idx, val in enumerate(y_coords)}
3326

34-
# 圧縮後の座標リストを作成
35-
compressed = [(x_map[x], y_map[y]) for x, y in points]
36-
37-
return compressed
27+
return [(x_map[x], y_map[y]) for x, y in points]

libs/coordinates_to_id.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
from typing import List, Tuple
2-
3-
4-
def coordinates_to_id(H: int, W: int) -> Tuple[List[List[int]], List[Tuple[int]]]:
5-
"""
6-
座標にID変換します
1+
def coordinates_to_id(h: int, w: int) -> tuple[list[list[int]], list[tuple[int, int]]]:
2+
"""座標を一次元のindexに変換する関数
73
84
返り値は、
95
最初のが、座標からid
106
二つめのが、idから座標
117
です
128
"""
13-
ItC = [[-1] * W for _ in [0] * H]
14-
CtI = [(-1, -1) for _ in [0] * (H * W)]
9+
ItC = [[-1] * w for _ in [0] * h]
10+
CtI = [(-1, -1) for _ in [0] * (h * w)]
1511

1612
i = 0
1713

18-
for x in range(H):
19-
for y in range(W):
14+
for x in range(h):
15+
for y in range(w):
2016
ItC[x][y] = i
2117
CtI[i] = (x, y)
2218
i += 1

libs/dijkstra.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import heapq
2-
from typing import List, Tuple
32

43

54
def dijkstra(
6-
graph: List[List[Tuple[int]]], startpoint: int = 0, output_prev: bool = False
7-
) -> List[int] | Tuple[List[int], List[int]]:
8-
"""
9-
ダイクストラ法です
5+
graph: list[list[tuple[int]]],
6+
startpoint: int = 0,
7+
output_prev: bool = False,
8+
) -> list[int] | tuple[list[int], list[int]]:
9+
"""ダイクストラ法のライブラリ
10+
1011
GraphW構造体を使う場合は、allメソッドで、そんまま入れてください
1112
定数倍速いのかは分かりません(いつも使っているフォーマット)
1213
経路復元したい場合は、output_prevをTrueにすればprevも返ってくるので、それを使用して復元してください
@@ -16,6 +17,7 @@ def dijkstra(
1617
prev = [-1] * len(graph)
1718
if not 0 <= startpoint < len(graph):
1819
raise IndexError("あのー0-indexedですか?")
20+
1921
used[startpoint] = 0
2022
PQ = [(0, startpoint)]
2123

@@ -38,5 +40,5 @@ def dijkstra(
3840

3941
if not output_prev:
4042
return used
41-
else:
42-
return used, prev
43+
44+
return used, prev

libs/dis_lib.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,29 @@
1-
from typing import Tuple
2-
3-
41
def euclid_dis(x1: int, y1: int, x2: int, y2: int) -> int:
5-
"""
6-
ユークリッド距離を計算します
2+
"""ユークリッド距離を計算する関数
73
84
注意:
95
この関数はsqrtを取りません(主に少数誤差用)
106
sqrtを取りたい場合は、自分で計算してください
117
"""
12-
138
return ((x1 - x2) ** 2) + ((y1 - y2) ** 2)
149

1510

1611
def manhattan_dis(x1: int, y1: int, x2: int, y2: int) -> int:
17-
"""
18-
マンハッタン距離を計算します
19-
"""
20-
12+
"""マンハッタン距離を計算する関数"""
2113
return abs(x1 - x2) + abs(y1 - y2)
2214

2315

24-
def manhattan_45turn(x: int, y: int) -> Tuple[int]:
25-
"""
26-
座標を45度回転します
16+
def manhattan_45turn(x: int, y: int) -> tuple[int]:
17+
"""マンハッタン距離用の座標を45度回転する関数
18+
2719
回転すると、マンハッタン距離が、チェビシェフ距離になるので、距離の最大値などが簡単に求められます
2820
"""
29-
3021
res_x = x - y
3122
res_y = x + y
3223

3324
return res_x, res_y
3425

3526

3627
def chebyshev_dis(x1: int, y1: int, x2: int, y2: int) -> int:
37-
"""
38-
チェビシェフ距離を計算します
39-
"""
40-
28+
"""チェビシェフ距離を計算する関数"""
4129
return max(abs(x1 - x2), abs(y1 - y2))

libs/dp.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# DPのテンプレート
2-
from typing import List
32

43

5-
def partial_sum_dp(lis: List[int], X: int) -> List[bool]:
6-
"""
7-
部分和dpのテンプレート
4+
def partial_sum_dp(lis: list[int], X: int) -> list[bool]:
5+
"""部分和dpのテンプレート
6+
87
lisは品物です
98
dp配列の長さは、Xにします
109
計算量は、O(X*len(L))みたいな感じ
@@ -28,8 +27,8 @@ def partial_sum_dp(lis: List[int], X: int) -> List[bool]:
2827

2928

3029
def knapsack_dp(lis: list[list[int]], W: int) -> int:
31-
"""
32-
ナップサック問題を一次元DPで解く
30+
"""ナップサックdpのテンプレート
31+
3332
lis: 品物のリスト [[重さ, 価値], ...]
3433
W: ナップサックの容量
3534
戻り値: 最大価値
@@ -41,16 +40,17 @@ def knapsack_dp(lis: list[list[int]], W: int) -> int:
4140

4241
for w, v in lis:
4342
if w < 0 or v < 0:
44-
raise ValueError("Weight and value must be non-negative")
43+
msg = "Weight and value must be non-negative"
44+
raise ValueError(msg)
4545
for k in reversed(range(W - w + 1)):
4646
dp[k + w] = max(dp[k + w], dp[k] + v)
4747

4848
return dp[W]
4949

5050

51-
def article_breakdown(lis: List[List[int]]) -> List[List[int]]:
52-
"""
53-
個数制限付きナップサックの品物を分解します
51+
def article_breakdown(lis: list[list[int]]) -> list[list[int]]:
52+
"""個数制限付きナップサック問題用の品物を分解する関数
53+
5454
個数の値が、各品物の一番右にあれば正常に動作します
5555
"""
5656
res = []

libs/dual_segtree.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from typing import Any, Callable
1+
from collections.abc import Callable
2+
from typing import Any
23

34

45
class DualSegmentTree:
5-
def __init__(self, op: Callable[[Any, Any], Any], e: Any, n: int) -> None:
6-
"""
7-
区間作用/一点取得のセグメント木
6+
def __init__(self, op: Callable[[Any, Any], Any], e, n: int) -> None:
7+
"""区間作用/一点取得のセグメント木
8+
89
opは区間作用用の関数
910
eは初期値
1011
vは長さ
@@ -16,9 +17,7 @@ def __init__(self, op: Callable[[Any, Any], Any], e: Any, n: int) -> None:
1617
self.data = [e] * (self.n * 2)
1718

1819
def apply(self, l, r, x) -> None:
19-
"""
20-
区間[l,r)にxを適用
21-
"""
20+
"""区間[l,r)にxを適用"""
2221
assert 0 <= l <= r <= self.n
2322
l += self.n
2423
r += self.n
@@ -35,9 +34,7 @@ def apply(self, l, r, x) -> None:
3534
r >>= 1
3635

3736
def get(self, p: int) -> Any:
38-
"""
39-
pの値を取得する
40-
"""
37+
"""pの値を取得する"""
4138
assert 0 <= p < self.n
4239

4340
res = self._e

libs/euler_tour.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
from typing import List, Tuple
2-
3-
41
class EulerTour:
5-
def __init__(self, edges: List[Tuple[int, int, int]], root: int = 0) -> None:
6-
"""
2+
def __init__(self, edges: list[tuple[int, int, int]], root: int = 0) -> None:
3+
"""オイラーツアーのライブラリ
4+
75
edges[i] = (u, v, w)
86
なお閉路がない、連結という前提 エラー処理をしていない
97
@@ -14,15 +12,14 @@ def __init__(self, edges: List[Tuple[int, int, int]], root: int = 0) -> None:
1412
Warning:
1513
ac-library-pythonを__init__内で使用しているので注意
1614
定数倍が遅い事に注意 あとメモリも注意 結構リストを使用している
17-
"""
18-
# assert len(edges) >= 1
1915
16+
"""
2017
from atcoder.segtree import SegTree
2118

2219
self.edges = edges
2320
self._n = max([max(u, v) for u, v, w in edges]) + 1
2421
self.root = root
25-
self.graph: List[List[Tuple[int, int, int]]] = [[] for _ in [0] * self._n]
22+
self.graph: list[list[tuple[int, int, int]]] = [[] for _ in [0] * self._n]
2623

2724
for i, (u, v, w) in enumerate(edges):
2825
self.graph[u].append((v, w, i))
@@ -37,12 +34,10 @@ def __init__(self, edges: List[Tuple[int, int, int]], root: int = 0) -> None:
3734
[(d, i) for i, d in enumerate(self.depth)],
3835
)
3936

40-
return
41-
4237
def _build(self) -> None:
43-
self.euler_tour: List[Tuple[int, int]] = [(0, -1)]
44-
self.edge_cost: List[int] = [0]
45-
self.depth: List[int] = [0]
38+
self.euler_tour: list[tuple[int, int]] = [(0, -1)]
39+
self.edge_cost: list[int] = [0]
40+
self.depth: list[int] = [0]
4641

4742
def dfs(cur: int, p: int = -1, d: int = 0) -> None:
4843
for nxt, w, i in self.graph[cur]:
@@ -78,8 +73,6 @@ def dfs(cur: int, p: int = -1, d: int = 0) -> None:
7873
self.last_arrival[u] = i
7974

8075
def lca(self, a: int, b: int) -> int:
81-
# assert 0 <= a < self._n and 0 <= b < self._n
82-
8376
l, r = (
8477
min(self.first_arrival[a], self.first_arrival[b]),
8578
max(self.last_arrival[a], self.last_arrival[b]),
@@ -92,10 +85,7 @@ def path_query_from_root(self, u: int) -> int:
9285
return self.segtree_edgecost.prod(0, self.first_arrival[u] + 1)
9386

9487
def path_query(self, a: int, b: int) -> int:
95-
"""
96-
aからbへの最短経路
97-
"""
98-
# assert 0 <= a < self._n and 0 <= b < self._n
88+
"""aからbへの最短経路"""
9989
try:
10090
l = self.lca(a, b)
10191
except IndexError:
@@ -108,6 +98,5 @@ def path_query(self, a: int, b: int) -> int:
10898
)
10999

110100
def change_edge_cost(self, i: int, w: int) -> None:
111-
# assert 0 <= i < len(self.edges)
112101
self.segtree_edgecost.set(self.edge_plus[i], w)
113102
self.segtree_edgecost.set(self.edge_minus[i], -w)

0 commit comments

Comments
 (0)