結果

問題 No.817 Coin donation
ユーザー NoneNone
提出日時 2021-03-04 22:22:15
言語 PyPy3
(7.3.13)
結果
AC  
実行時間 327 ms / 2,000 ms
コード長 3,317 bytes
コンパイル時間 714 ms
コンパイル使用メモリ 87,156 KB
実行使用メモリ 150,632 KB
最終ジャッジ日時 2023-07-28 04:30:29
合計ジャッジ時間 3,862 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 73 ms
71,264 KB
testcase_01 AC 76 ms
75,248 KB
testcase_02 AC 77 ms
75,328 KB
testcase_03 AC 75 ms
75,424 KB
testcase_04 AC 77 ms
75,384 KB
testcase_05 AC 91 ms
76,824 KB
testcase_06 AC 114 ms
83,588 KB
testcase_07 AC 120 ms
86,992 KB
testcase_08 AC 233 ms
127,928 KB
testcase_09 AC 125 ms
88,984 KB
testcase_10 AC 327 ms
150,548 KB
testcase_11 AC 322 ms
150,632 KB
testcase_12 AC 317 ms
150,528 KB
testcase_13 AC 69 ms
71,444 KB
testcase_14 AC 71 ms
71,480 KB
testcase_15 AC 70 ms
71,280 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class Imos:
    def __init__(self,decrement=1):
        self.decode=set()
        self.data=[]
        self.idx=decrement

    def update_range(self,l,r,k):
        """ update elems in [l,r) """
        data,decode=self.data,self.decode
        l, r = l-self.idx, r-self.idx
        data.append((l,r,k))
        decode.add(l)
        decode.add(r)


    def simulate(self):
        data,decode=self.data,self.decode
        decode=self.decode=sorted(list(decode))
        code=self.code={e:i for i,e in enumerate(decode)}
        N=self.N=len(self.decode)
        imos=[0]*N
        acc=[0]

        for l,r,k in data:
            l,r=code[l],code[r]
            imos[l]+=k
            imos[r]-=k

        for s in imos:
            acc.append(acc[-1]+s)
        self.acc=acc[1:]

    def get(self,x):
        acc,decode=self.acc,self.decode
        x=x-self.idx
        return acc[bisect_right(decode,x)-1]

    def get_range(self,l,r):
        """
        sum elems in [l,r)
        計算量: O(N) ; N=number of updates
        備考: 区間取得をO(1)でするならば、遅延セグ木が必要
        """
        def f(x):
            """ 累積後の各要素への作用 """
            return x

        acc,decode,code=self.acc,self.decode,self.code
        l,r=l-self.idx,r-self.idx
        il,ir=bisect_right(decode,l)-1, bisect_right(decode,r)-1
        res=0
        res+=(decode[il+1]-l)*f(acc[il])
        for i in range(il+1,ir):
            """
            座圧で全ての区間をサイズ1にしたので、 
            (decode[i+1]-decode[i])を掛けて元に戻している
            区間内では全ての要素が同じ値を持つので、
            単純にacc[i]を(decode[i+1]-decode[i])倍するだけでよい
            """
            res+=(decode[i+1]-decode[i])*f(acc[i])
        res+=(r-decode[ir])*f(acc[ir])
        return res

    def get_all_range(self):
        return self.get_range(self.idx, self.decode[-1]+1+self.idx)

    def __getitem__(self, x):
        acc,decode=self.acc,self.decode
        x=x-self.idx
        return acc[bisect_right(decode,x)-1]

    def __iter__(self):
        for i in range(self.decode[-1]):
            yield self.get(i+self.idx)

    def __str__(self):
        return str(list(self))

def max2(x,y):
    return x if x > y else y


def binary_search_int(ok, ng, test):
    """
    :param ok: solve(x) = True を必ず満たす点
    :param ng: solve(x) = False を必ず満たす点
    """
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if test(mid):
            ok = mid
        else:
            ng = mid
    return ok

#########################################################
def example():
    global input
    example = iter(
        """
10 3
1 5
4 8
12 14
        """
            .strip().split("\n"))
    input = lambda: next(example)
#########################################################
import sys
input = sys.stdin.readline
from bisect import bisect_left, bisect_right

# example()

N,K=map(int, input().split())
imos=Imos(decrement=1)
for _ in range(N):
    l, r = map(int, input().split())    # 区間は閉区間 [l,r] で与えられる
    imos.update_range(l,r+1,1)

imos.simulate()

def test(x):
    return imos.get_range(0,x)<K



res=binary_search_int(0,10**18,test)

print(res)
0