結果
| 問題 |
No.2758 RDQ
|
| コンテスト | |
| ユーザー |
ともえ
|
| 提出日時 | 2024-05-17 21:49:52 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,393 bytes |
| コンパイル時間 | 484 ms |
| コンパイル使用メモリ | 82,340 KB |
| 実行使用メモリ | 330,072 KB |
| 最終ジャッジ日時 | 2024-12-20 13:34:32 |
| 合計ジャッジ時間 | 53,126 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 5 TLE * 16 |
ソースコード
class SegmentTree:
def __init__(self, n, identity_e, combine_f):
"""
配列を 2 * n 個のノードで初期化する(0-indexed, 頂点は1から)
n: 列の長さ
identity_e: 単位元
combine_f: 2つのデータから値を合成するための関数
node: 各頂点の中身
"""
self._n = n
self._size = 1
while self._size < self._n:
self._size <<= 1
self._identity_e = identity_e
self._combine_f = combine_f
self._node = [self._identity_e] * (2 * self._size)
def build(self, array):
"""
配列 array の各要素を登録する
"""
# assert: True なら何も起こらない, False なら AssertionError を返す
assert len(array) == self._n
for idx, value in enumerate(array, start = self._size):
self._node[idx] = value
for idx in range(self._size - 1, 0, -1):
self._node[idx] = self._combine_f(
self._node[idx << 1 | 0], # 左の子
self._node[idx << 1 | 1], # 右の子
)
def update(self, idx, value):
"""
一点更新: 位置 idx(0-indexed) を値 value で更新
"""
i = self._size + idx
self._node[i] = value
while i > 1:
i >>= 1
self._node[i] = self._combine_f(
self._node[i << 1 | 0], # 左の子
self._node[i << 1 | 1], # 右の子
)
def fold(self, L, R):
"""
区間取得: 区間 [l, r) (0-indexed) 内の要素について、l 番目から順に
combine_f を適用した結果を返す(交換法則が前提になくても良い)
"""
L += self._size
R += self._size
value_L = self._identity_e
value_R = self._identity_e
while L < R:
if L & 1:
value_L = self._combine_f(value_L, self._node[L])
L += 1
if R & 1:
R -= 1
value_R = self._combine_f(self._node[R], value_R)
L >>= 1
R >>= 1
return self._combine_f(value_L, value_R)
def __str__(self):
return ', '.join([str(x) for x in self._node])
def Divisors(n):
# 約数のリストを返す関数
divisors = []
L = n ** 0.5
for i in range(1, int(L) + 1):
if n % i == 0:
divisors.append(i)
if i != n // i:
divisors.append(n // i)
return divisors
from collections import defaultdict
def op(a, b):
if len(a) < len(b):
res = {k: v for k, v in b.items()}
for k, v in a.items():
if k in res:
res[k] += v
else:
res[k] = v
return res
res = {k: v for k, v in a.items()}
for k, v in b.items():
if k in res:
res[k] += v
else:
res[k] = v
return res
N, Q = map(int, input().split())
A = list(map(int, input().split()))
size = 5 * 10**4
seg = SegmentTree(size, {}, op)
for i, a in enumerate(A):
res = defaultdict(int)
for v in Divisors(a):
res[v] = 1
seg.update(i, res)
for _ in range(Q):
l, r, k = map(int, input().split())
x = seg.fold(l-1, r)
if k in x:
print(x[k])
else:
print(0)
ともえ