Skip to content

Commit 5079c6f

Browse files
committed
feat: 平方分割ライブラリを追加した
1 parent 248f705 commit 5079c6f

File tree

4 files changed

+140
-2
lines changed

4 files changed

+140
-2
lines changed

code/main.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,75 @@ def mo_algorithm(
13551355
return res
13561356

13571357

1358+
import math
1359+
from typing import Any, Callable, List
1360+
1361+
1362+
class SquareDivision:
1363+
def __init__(self, lis: List[Any], op: Callable[[Any, Any], Any]) -> None:
1364+
self.n = len(lis)
1365+
self.op = op
1366+
self.block_size = math.isqrt(self.n)
1367+
self.blocks = []
1368+
self.lis = lis[:]
1369+
1370+
for i in range(0, self.n, self.block_size):
1371+
block_val = lis[i]
1372+
for k in range(i + 1, min(i + self.block_size, self.n)):
1373+
block_val = self.op(block_val, lis[k])
1374+
self.blocks.append(block_val)
1375+
1376+
self.m = len(self.blocks)
1377+
1378+
def get_block_index_left(self, i: int) -> int:
1379+
return i // self.block_size
1380+
1381+
def get_block_index_right(self, i: int) -> int:
1382+
return (i + self.block_size - 1) // self.block_size
1383+
1384+
def prod(self, l: int, r: int) -> Any:
1385+
"""
1386+
rは0-indexedなのに注意してください
1387+
"""
1388+
assert 0 <= l <= r < self.n
1389+
1390+
l_block_left = self.get_block_index_left(l)
1391+
r_block_left = self.get_block_index_left(r)
1392+
1393+
if l_block_left == r_block_left:
1394+
res = self.lis[l]
1395+
for k in range(l + 1, r + 1):
1396+
res = self.op(res, self.lis[k])
1397+
return res
1398+
1399+
res = self.lis[l]
1400+
for i in range(l + 1, min((l_block_left + 1) * self.block_size, self.n)):
1401+
res = self.op(res, self.lis[i])
1402+
1403+
for block_ind in range(l_block_left + 1, r_block_left):
1404+
res = self.op(res, self.blocks[block_ind])
1405+
1406+
for i in range(r_block_left * self.block_size, r + 1):
1407+
res = self.op(res, self.lis[i])
1408+
1409+
return res
1410+
1411+
def update(self, i: int, x: Any) -> None:
1412+
assert 0 <= i < self.n
1413+
self.lis[i] = x
1414+
block_ind = self.get_block_index_left(i)
1415+
start = block_ind * self.block_size
1416+
end = min(start + self.block_size, self.n)
1417+
if start < self.n:
1418+
self.blocks[block_ind] = self.lis[start]
1419+
for j in range(start + 1, end):
1420+
self.blocks[block_ind] = self.op(self.blocks[block_ind], self.lis[j])
1421+
1422+
def get(self, i: int) -> Any:
1423+
assert 0 <= i < self.n
1424+
return self.lis[i]
1425+
1426+
13581427
from typing import List
13591428

13601429

libs/square-division.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import math
2+
from typing import Any, Callable, List
3+
4+
5+
class SquareDivision:
6+
def __init__(self, lis: List[Any], op: Callable[[Any, Any], Any]) -> None:
7+
self.n = len(lis)
8+
self.op = op
9+
self.block_size = math.isqrt(self.n)
10+
self.blocks = []
11+
self.lis = lis[:]
12+
13+
for i in range(0, self.n, self.block_size):
14+
block_val = lis[i]
15+
for k in range(i + 1, min(i + self.block_size, self.n)):
16+
block_val = self.op(block_val, lis[k])
17+
self.blocks.append(block_val)
18+
19+
self.m = len(self.blocks)
20+
21+
def get_block_index_left(self, i: int) -> int:
22+
return i // self.block_size
23+
24+
def get_block_index_right(self, i: int) -> int:
25+
return (i + self.block_size - 1) // self.block_size
26+
27+
def prod(self, l: int, r: int) -> Any:
28+
"""
29+
rは0-indexedなのに注意してください
30+
"""
31+
assert 0 <= l <= r < self.n
32+
33+
l_block_left = self.get_block_index_left(l)
34+
r_block_left = self.get_block_index_left(r)
35+
36+
if l_block_left == r_block_left:
37+
res = self.lis[l]
38+
for k in range(l + 1, r + 1):
39+
res = self.op(res, self.lis[k])
40+
return res
41+
42+
res = self.lis[l]
43+
for i in range(l + 1, min((l_block_left + 1) * self.block_size, self.n)):
44+
res = self.op(res, self.lis[i])
45+
46+
for block_ind in range(l_block_left + 1, r_block_left):
47+
res = self.op(res, self.blocks[block_ind])
48+
49+
for i in range(r_block_left * self.block_size, r + 1):
50+
res = self.op(res, self.lis[i])
51+
52+
return res
53+
54+
def update(self, i: int, x: Any) -> None:
55+
assert 0 <= i < self.n
56+
self.lis[i] = x
57+
block_ind = self.get_block_index_left(i)
58+
start = block_ind * self.block_size
59+
end = min(start + self.block_size, self.n)
60+
if start < self.n:
61+
self.blocks[block_ind] = self.lis[start]
62+
for j in range(start + 1, end):
63+
self.blocks[block_ind] = self.op(self.blocks[block_ind], self.lis[j])
64+
65+
def get(self, i: int) -> Any:
66+
assert 0 <= i < self.n
67+
return self.lis[i]

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" "mo.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" "square-division.py" "bit.py" "dis_lib.py" "alias.py" "utils.py"; do
1111

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

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ version = "0.1.0"
44
description = "Add your description here"
55
readme = "README.md"
66
requires-python = ">=3.10"
7-
dependencies = ["debugpy>=1.8.14"]
7+
dependencies = [
8+
"debugpy>=1.8.14",
9+
]
810

911
[tool.ruff]
1012
line-length = 88

0 commit comments

Comments
 (0)