Submission #44087990


Source Code Expand

class BalancingTree:
    # https://qiita.com/Kiri8128/items/6256f8559f0026485d90
    def __init__(self, n, ibl = 0):
        self.N = n
        if 1:
            self.S = {1<<n} # <-- 存在チェックをしないならいらない
        self.identifying_bit_length = ibl
        self.root = self.node(1<<n, 1<<n, ibl, 0)

    def add(self, v): # v を追加(既に存在する場合はなにもしない)
        v += 1
        # 存在する元を追加しないことが分かっている場合はこの確認は不要
        ### ここから
        if 1:
            if v in self.S:
                return 0 
            self.S.add(v)
        ### ここまで
        nd = self.root
        while True:
            nd.size += 1
            nd.sum += v - 1 >> self.identifying_bit_length
            if v == nd.value:
                #####
                return 0
            else:
                mi, ma = min(v, nd.value), max(v, nd.value)
                if mi < nd.pivot:
                    nd.value = ma
                    if nd.left:
                        nd = nd.left
                        v = mi
                    else:
                        p = nd.pivot
                        nd.left = self.node(mi, p - (p&-p)//2, self.identifying_bit_length)
                        break
                else:
                    nd.value = mi
                    if nd.right:
                        nd = nd.right
                        v = ma
                    else:
                        p = nd.pivot
                        nd.right = self.node(ma, p + (p&-p)//2, self.identifying_bit_length)
                        break

    def leftmost(self, nd):
        while nd.left:
            nd = nd.left
        return nd

    def rightmost(self, nd):
        while nd.right:
            nd = nd.right
        return nd

    def find_l(self, v): # vより真に小さいやつの中での最大値(なければ-1)
        v += 1
        nd = self.root
        prev = 0
        if nd.value < v: prev = nd.value
        while True:
            if v <= nd.value:
                if nd.left:
                    nd = nd.left
                else:
                    return prev - 1
            else:
                prev = nd.value
                if nd.right:
                    nd = nd.right
                else:
                    return prev - 1

    def find_r(self, v): # vより真に大きいやつの中での最小値(なければRoot)
        v += 1
        nd = self.root
        prev = 0
        if nd.value > v: prev = nd.value
        while True:
            if v < nd.value:
                prev = nd.value
                if nd.left:
                    nd = nd.left
                else:
                    return prev - 1
            else:
                if nd.right:
                    nd = nd.right
                else:
                    return prev - 1

    @property
    def max(self):
        return self.find_l((1<<self.N)-1)

    @property
    def min(self):
        return self.find_r(-1)
    
    @property
    def sum(self):
        return self.root.sum

    def delete(self, v, nd = None, prev = None, chk = 0): # 値がvのノードがあれば削除(なければ何もしない)
        v += 1
        ### ここから
        if 1:
            if not chk:
                if v not in self.S: return 0
                self.S.remove(v)
        ### ここまで
        if not nd: nd = self.root
        if not prev: prev = nd
        while 1:
            while v != nd.value:
                nd.size -= 1
                nd.sum -= v - 1 >> self.identifying_bit_length
                prev = nd
                if v <= nd.value:
                    if nd.left:
                        nd = nd.left
                    else:
                        #####
                        return
                else:
                    if nd.right:
                        nd = nd.right
                    else:
                        #####
                        return
            nd.size -= 1
            nd.sum -= v - 1 >> self.identifying_bit_length

            if (not nd.left) and (not nd.right):
                if not prev.left:
                    prev.right = None
                elif not prev.right:
                    prev.left = None
                else:
                    if nd.pivot == prev.left.pivot:
                        prev.left = None
                    else:
                        prev.right = None
                break
            elif nd.right:
                nd.value = self.leftmost(nd.right).value
                v, nd, prev = nd.value, nd.right, nd
                continue
            else:
                nd.value = self.rightmost(nd.left).value
                v, nd, prev = nd.value, nd.left, nd
                continue
    
    def count_less_than(self, v):
        v += 1
        re = 0
        nd = self.root
        while 1:
            if nd.value < v:
                re += (nd.left.size if nd.left else 0) + 1
                if nd.right:
                    nd = nd.right
                else:
                    return re
            else:
                if nd.left:
                    nd = nd.left
                else:
                    return re
    def count_not_less_than(self, v):
        return self.root.size - 1 - self.count_less_than(v)
    def sum_of_first_k_elements(self, k, nd = None):
        if not nd:
            if k >= self.root.size - 1:
                return self.root.sum
            if k <= 0:
                return 0
            nd = self.root
        re = 0
        while 1:
            if nd.left:
                l = nd.left.size
                if k < l:
                    nd = nd.left
                elif k > l:
                    re += nd.left.sum + (nd.value - 1 >> self.identifying_bit_length)
                    k -= l + 1
                    nd = nd.right
                else:
                    re += nd.left.sum
                    return re
            else:
                l = 0
                if k > l:
                    re += (nd.value - 1 >> self.identifying_bit_length)
                    k -= l + 1
                    nd = nd.right
                else:
                    return re
    def sum_less_than(self, v):
        v += 1
        re = 0
        nd = self.root
        while 1:
            if nd.value < v:
                re += (nd.left.sum if nd.left else 0) + (nd.value - 1 >> self.identifying_bit_length)
                if nd.right:
                    nd = nd.right
                else:
                    return re
            else:
                if nd.left:
                    nd = nd.left
                else:
                    return re
    def sum_not_less_than(self, v):
        return self.root.sum - 1 - self.sum_less_than(v)
    def kth_smallest(self, k, nd = None):
        if not nd:
            assert 0 <= k < self.root.size - 1
            nd = self.root
        while 1:
            l = nd.left.size if nd.left else 0
            if k < l:
                nd = nd.left
            elif k > l:
                k -= l + 1
                nd = nd.right
            else:
                return nd.value - 1
    def kth_largest(self, k, nd = None):
        if not nd:
            assert 0 <= k < self.root.size - 1
            nd = self.root.left
        while 1:
            r = nd.right.size if nd.right else 0
            if k < r:
                nd = nd.right
            elif k > r:
                k -= r + 1
                nd = nd.left
            else:
                return nd.value - 1
    
    def __getitem__(self, k):
        if type(k) == int:
            if 0 <= k < self.root.size - 1:
                return self.kth_smallest(k)
            if 0 <= ~k < self.root.size - 1:
                return self.kth_largest(~k)
        
        l = k.start
        if l is None:
            l = 0
        elif l < 0:
            l = self.root.size - 1 + l
        r = k.stop
        if r is None:
            r = self.root.size - 1
        if r < 0:
            r = self.root.size - 1 + r
        if l >= r:
            return 0
        return self.sum_of_first_k_elements(r) - (self.sum_of_first_k_elements(l) if l else 0)
    
    def __contains__(self, v: int) -> bool:
        return v + 1 in self.S

    class node:
        def __init__(self, v, p, identifying_bit_length, s = None):
            self.value = v
            self.pivot = p
            self.left = None
            self.right = None
            self.size = 1
            if s is None:
                s = v - 1 >> identifying_bit_length
            self.sum = s

    def debug(self):
        def debug_info(nd_):
            return (nd_.value - 1, nd_.sum, nd_.pivot - 1, nd_.left.value - 1 if nd_.left else -1, nd_.right.value - 1 if nd_.right else -1, nd_.size)

        def debug_node(nd):
            re = []
            if nd.left:
                re += debug_node(nd.left)
            if nd.value: re.append(debug_info(nd))
            if nd.right:
                re += debug_node(nd.right)
            return re
        print("Debug - root =", self.root.value - 1, debug_node(self.root)[:50])

    def debug_list(self):
        def debug_node(nd):
            re = []
            if nd.left:
                re += debug_node(nd.left)
            if nd.value: re.append(nd.value - 1)
            if nd.right:
                re += debug_node(nd.right)
            return re
        return debug_node(self.root)[:-1]

####################
import sys
input = lambda: sys.stdin.readline().rstrip()
K = 20
bt = BalancingTree(30 + K, K)
N, M = map(int, input().split())
A = []
B = []
for i in range(N):
    t, x = map(int, input().split())
    if t == 0:
        bt.add((x << K) + i)
    elif t == 1:
        A.append((x << K) + i)
    else:
        B.append(x)
A.sort()
B.sort()
ans = 0
while M > 0:
    ans = max(ans, bt[-M:])
    if not A or not B:
        break
    for _ in range(B.pop()):
        if not A:
            break
        bt.add(A.pop())
    M -= 1
print(ans)

Submission Info

Submission Time
Task F - Cans and Openers
User Kiri8128
Language PyPy3 (7.3.0)
Score 500
Code Size 10413 Byte
Status AC
Exec Time 531 ms
Memory 148496 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 500 / 500
Status
AC × 3
AC × 46
Set Name Test Cases
Sample sample00.txt, sample01.txt, sample02.txt
All sample00.txt, sample01.txt, sample02.txt, testcase00.txt, testcase01.txt, testcase02.txt, testcase03.txt, testcase04.txt, testcase05.txt, testcase06.txt, testcase07.txt, testcase08.txt, testcase09.txt, testcase10.txt, testcase11.txt, testcase12.txt, testcase13.txt, testcase14.txt, testcase15.txt, testcase16.txt, testcase17.txt, testcase18.txt, testcase19.txt, testcase20.txt, testcase21.txt, testcase22.txt, testcase23.txt, testcase24.txt, testcase25.txt, testcase26.txt, testcase27.txt, testcase28.txt, testcase29.txt, testcase30.txt, testcase31.txt, testcase32.txt, testcase33.txt, testcase34.txt, testcase35.txt, testcase36.txt, testcase37.txt, testcase38.txt, testcase39.txt, testcase40.txt, testcase41.txt, testcase42.txt
Case Name Status Exec Time Memory
sample00.txt AC 63 ms 63792 KiB
sample01.txt AC 48 ms 63616 KiB
sample02.txt AC 51 ms 63644 KiB
testcase00.txt AC 474 ms 148496 KiB
testcase01.txt AC 152 ms 84816 KiB
testcase02.txt AC 152 ms 84688 KiB
testcase03.txt AC 403 ms 146084 KiB
testcase04.txt AC 409 ms 147228 KiB
testcase05.txt AC 425 ms 146064 KiB
testcase06.txt AC 401 ms 145912 KiB
testcase07.txt AC 249 ms 98432 KiB
testcase08.txt AC 330 ms 112156 KiB
testcase09.txt AC 377 ms 122232 KiB
testcase10.txt AC 474 ms 139104 KiB
testcase11.txt AC 258 ms 98672 KiB
testcase12.txt AC 328 ms 112420 KiB
testcase13.txt AC 346 ms 117216 KiB
testcase14.txt AC 493 ms 137920 KiB
testcase15.txt AC 245 ms 95476 KiB
testcase16.txt AC 312 ms 112900 KiB
testcase17.txt AC 375 ms 123484 KiB
testcase18.txt AC 437 ms 138816 KiB
testcase19.txt AC 240 ms 94896 KiB
testcase20.txt AC 321 ms 111408 KiB
testcase21.txt AC 376 ms 122080 KiB
testcase22.txt AC 449 ms 138260 KiB
testcase23.txt AC 355 ms 139824 KiB
testcase24.txt AC 420 ms 146784 KiB
testcase25.txt AC 435 ms 139600 KiB
testcase26.txt AC 531 ms 147240 KiB
testcase27.txt AC 338 ms 119156 KiB
testcase28.txt AC 396 ms 125052 KiB
testcase29.txt AC 358 ms 120520 KiB
testcase30.txt AC 395 ms 127236 KiB
testcase31.txt AC 300 ms 115508 KiB
testcase32.txt AC 372 ms 124336 KiB
testcase33.txt AC 369 ms 125860 KiB
testcase34.txt AC 406 ms 127072 KiB
testcase35.txt AC 318 ms 117168 KiB
testcase36.txt AC 338 ms 121264 KiB
testcase37.txt AC 361 ms 123024 KiB
testcase38.txt AC 393 ms 126432 KiB
testcase39.txt AC 310 ms 117296 KiB
testcase40.txt AC 356 ms 122596 KiB
testcase41.txt AC 393 ms 125756 KiB
testcase42.txt AC 392 ms 126400 KiB