Skip to content

Commit efa397c

Browse files
committed
feat: created mo's algolithm library
1 parent e38833f commit efa397c

File tree

5 files changed

+102
-12
lines changed

5 files changed

+102
-12
lines changed

code/main.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,57 @@ def lcp_sum(self, value: str) -> int:
13041304
return result
13051305

13061306

1307+
import math
1308+
from typing import Any, Callable, List
1309+
1310+
1311+
def mo_algorithm(
1312+
N: int,
1313+
queries: List[Any],
1314+
add: Callable[[int], Any],
1315+
delete: Callable[[int], Any],
1316+
getvalue: Callable[[], Any],
1317+
) -> List[Any]:
1318+
"""
1319+
Mo's algorithmの関数
1320+
queriesは、(左端, 右端)で1-indexed
1321+
addはあるindexが追加される時の値を現在の値にする
1322+
deleteはあるindexが削除される時の値を現在の値にする
1323+
getvalueは現在の値を返す
1324+
"""
1325+
Q = len(queries)
1326+
res = [None] * Q
1327+
M = int(max(1, 1.0 * N / max(1, math.sqrt(Q * 2.0 / 3.0))))
1328+
1329+
queries = [(l, r, i) for i, (l, r) in enumerate(queries)]
1330+
queries.sort(key=lambda x: (x[0] // M, x[1] if (x[0] // M) % 2 == 0 else -x[1]))
1331+
1332+
cl, cr = 0, -1
1333+
1334+
for l, r, ind in queries:
1335+
l -= 1
1336+
r -= 1
1337+
while cl > l:
1338+
cl -= 1
1339+
add(cl)
1340+
1341+
while cr < r:
1342+
cr += 1
1343+
add(cr)
1344+
1345+
while cl < l:
1346+
delete(cl)
1347+
cl += 1
1348+
1349+
while cr > r:
1350+
delete(cr)
1351+
cr -= 1
1352+
1353+
res[ind] = getvalue()
1354+
1355+
return res
1356+
1357+
13071358
from typing import List
13081359

13091360

libs/mo.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import math
2+
from typing import Any, Callable, List
3+
4+
5+
def mo_algorithm(
6+
N: int,
7+
queries: List[Any],
8+
add: Callable[[int], Any],
9+
delete: Callable[[int], Any],
10+
getvalue: Callable[[], Any],
11+
) -> List[Any]:
12+
"""
13+
Mo's algorithmの関数
14+
queriesは、(左端, 右端)で1-indexed
15+
addはあるindexが追加される時の値を現在の値にする
16+
deleteはあるindexが削除される時の値を現在の値にする
17+
getvalueは現在の値を返す
18+
"""
19+
Q = len(queries)
20+
res = [None] * Q
21+
M = int(max(1, 1.0 * N / max(1, math.sqrt(Q * 2.0 / 3.0))))
22+
23+
queries = [(l, r, i) for i, (l, r) in enumerate(queries)]
24+
queries.sort(key=lambda x: (x[0] // M, x[1] if (x[0] // M) % 2 == 0 else -x[1]))
25+
26+
cl, cr = 0, -1
27+
28+
for l, r, ind in queries:
29+
l -= 1
30+
r -= 1
31+
while cl > l:
32+
cl -= 1
33+
add(cl)
34+
35+
while cr < r:
36+
cr += 1
37+
add(cr)
38+
39+
while cl < l:
40+
delete(cl)
41+
cl += 1
42+
43+
while cr > r:
44+
delete(cr)
45+
cr -= 1
46+
47+
res[ind] = getvalue()
48+
49+
return res

merge_file.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ echo "新しいmain.py作成完了"
77
# テンプレ
88
# /bin/cat python/<filename>.py >> code/main.py
99

10-
for file_name in "import.py" "standard_input.py" "math_func.py" "array_create.py" "binary_search.py" "modint.py" "yn_func.py" "grid.py" "coordinates_to_id.py" "dijkstra.py" "get_path.py" "dp.py" "coordinate_compression.py" "memo.py" "lca_weight.py" "rollinghash.py" "graph.py" "unionfind.py" "potential_unionfind.py" "heap.py" "trie.py" "bit.py" "dis_lib.py" "alias.py" "utils.py"; do
10+
for file_name in "import.py" "standard_input.py" "math_func.py" "array_create.py" "binary_search.py" "modint.py" "yn_func.py" "grid.py" "coordinates_to_id.py" "dijkstra.py" "get_path.py" "dp.py" "coordinate_compression.py" "memo.py" "lca_weight.py" "rollinghash.py" "graph.py" "unionfind.py" "potential_unionfind.py" "heap.py" "trie.py" "mo.py" "bit.py" "dis_lib.py" "alias.py" "utils.py"; do
1111

1212
cat libs/${file_name} >>code/main.py
1313
done

mise.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ run = "./pre_commit.bash"
1010

1111
[env]
1212
_.python.venv = { path = ".venv" }
13+
PYTHON_PATH = "."

pyproject.toml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,3 @@ line-length = 88
1111

1212
[tool.ruff.lint]
1313
select = ["C9", "E", "F", "W", "I", "ANN"]
14-
ignore = [
15-
"F401",
16-
"E402",
17-
"E741",
18-
"F405",
19-
"F403",
20-
"I001",
21-
"E722",
22-
"E501",
23-
"F811",
24-
]

0 commit comments

Comments
 (0)