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)