結果

問題 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
権限があれば一括ダウンロードができます

ソースコード

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):
    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)
0