結果

問題 No.3313 Matryoshka
コンテスト
ユーザー LyricalMaestro
提出日時 2026-01-29 23:53:33
言語 PyPy3
(7.3.17)
結果
TLE  
実行時間 -
コード長 2,700 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 335 ms
コンパイル使用メモリ 82,416 KB
実行使用メモリ 165,444 KB
最終ジャッジ日時 2026-01-29 23:53:54
合計ジャッジ時間 20,545 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 15 TLE * 1 -- * 19
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

# https://yukicoder.me/problems/no/3313


class SegmentTree:
    """
    非再帰版セグメント木。
    更新は「加法」、取得は「最大値」のもの限定。
    """

    def __init__(self, init_array):
        n = 1
        while n < len(init_array):
            n *= 2
        
        self.size = n
        self.array = [[] for _ in range(2 * self.size)]

    def set(self, x, j):
        index = self.size + x
        self.array[index].append(j)
        while index > 1:
            index //= 2
            self._op(self.array[index], self.array[2 * index], self.array[2 * index + 1])
    
    def _op(self, array, left, right):
        array.clear()
        l_index = 0
        r_index = 0
        while l_index < len(left) or r_index < len(right):
            if l_index < len(left) and r_index < len(right):
                if left[l_index] <= right[r_index]:
                    array.append(left[l_index])
                    l_index += 1
                else:
                    array.append(right[r_index])
                    r_index += 1
            elif l_index < len(left):
                array.append(left[l_index])
                l_index += 1
            elif r_index < len(right):
                array.append(right[r_index])
                r_index += 1

    def _calc(self, array, index):
        if len(array) == 0:
            return 0

        if index <= array[0]:
            return len(array)
        
        low = 0
        high = len(array) - 1
        while high - low > 1:
            mid = (high + low) // 2
            if array[mid] < index:
                low = mid
            else:
                high = mid
        if array[high] < index:
            return len(array) - (high + 1)
        else:
            return len(array) - (low + 1)


    def get_max(self, l, r, i):
        L = self.size + l; R = self.size + r

        # 2. 区間[l, r)の最大値を求める
        s = 0
        while L < R:
            if R & 1:
                R -= 1
                s += self._calc(self.array[R], i)
            if L & 1:
                s += self._calc(self.array[L], i)
                L += 1
            L >>= 1; R >>= 1
        return s


def main():
    N = int(input())
    lr = []
    max_r = 0
    for i in range(N):
        l, r = map(int, input().split())
        max_r = max(max_r, r)
        lr.append((l, r, i))

    lr.sort(key=lambda x : x[0],  reverse=True)
    seg_tree = SegmentTree([0] * (max_r + 1))

    answer = 0
    for l, r, index in lr:
        ans = seg_tree.get_max(l, r, index)
        answer += ans
        seg_tree.set(r, index)
    print(answer)


            

    




if __name__ == "__main__":
    main()
0