結果

問題 No.2758 RDQ
ユーザー ともえ
提出日時 2024-05-17 21:44:37
言語 PyPy3
(7.3.15)
結果
TLE  
実行時間 -
コード長 3,109 bytes
コンパイル時間 160 ms
コンパイル使用メモリ 82,136 KB
実行使用メモリ 328,600 KB
最終ジャッジ日時 2024-12-20 13:29:37
合計ジャッジ時間 52,962 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 5 TLE * 16
権限があれば一括ダウンロードができます

ソースコード

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