結果

問題 No.2758 RDQ
ユーザー ともえともえ
提出日時 2024-05-17 21:44:37
言語 PyPy3
(7.3.15)
結果
TLE  
実行時間 -
コード長 3,109 bytes
コンパイル時間 369 ms
コンパイル使用メモリ 82,364 KB
実行使用メモリ 162,536 KB
最終ジャッジ日時 2024-05-17 21:44:49
合計ジャッジ時間 4,106 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 43 ms
63,292 KB
testcase_01 AC 42 ms
57,428 KB
testcase_02 AC 40 ms
57,280 KB
testcase_03 AC 48 ms
62,864 KB
testcase_04 AC 39 ms
56,752 KB
testcase_05 TLE -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

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):
    res = defaultdict(int)
    for k, v in a.items():
        res[k] += v
    for k, v in b.items():
        res[k] += v
    return res

N, Q = map(int, input().split())
A = list(map(int, input().split()))

size = 5 * 10**4
seg = SegmentTree(size, defaultdict(int), 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())
    print(seg.fold(l-1, r)[k])
0