aacord’s memo

abcを中心にpythonで解いた問題のメモ、整理をしています。緑になった。

abc 106 D - AtCoder Express 2 (python)

まんまこれ。
区間に含まれる区間の数をカウントするクエリにたくさん答えたい - 問題解決の宝石箱
終点でソートすることにより、それまでに出てきた区間の終点が、今見ている区間の終点よりも小さいことが保証され、始点の位置だけセグ木で保管すれば、クエリに完全に含まれる個数が分かる。賢いね。

class segment_():
    def __init__(self,n,ide_ele,segfunc):
        self.ide_ele = ide_ele
        self.num = 1 << n.bit_length()
        self.seg = [self.ide_ele] * 2 * self.num
        self.segfunc = segfunc

    def update1(self, k):
        k += self.num
        self.seg[k] += 1
        while k:
            k >>= 1
            self.seg[k] = self.segfunc(self.seg[k * 2], self.seg[k * 2 + 1])

    def query(self, p, q):
        if q < p:
            return self.ide_ele
        p += self.num;
        q += self.num
        res = self.ide_ele
        while p < q:
            if p & 1 == 1:
                res = self.segfunc(res, self.seg[p])
                p += 1
            if q & 1 == 1:
                q -= 1
                res = self.segfunc(res, self.seg[q])
            p >>= 1;
            q >>= 1
        return res

def main():
  import sys
  read = sys.stdin.buffer.read
  readline = sys.stdin.buffer.readline
  readlines = sys.stdin.buffer.readlines
  from operator import itemgetter

  N,M,Q = map(int,readline().split())
  S = segment_(N,0,lambda a, b: a+b)
  chk = []
  for i in range(M):
    L,R = map(int,readline().split())
    chk.append((1,L,R,i))
  for i in range(Q):
    l,r = map(int,readline().split())
    chk.append((2,l,r,i))

  chk.sort(key=itemgetter(2))
  ans = [0]*Q
  for a,l,r,i in chk:
    if a == 1:
      S.update1(l)
    else:
      ans[i] = S.query(l,r+1)

  print(*ans,sep='\n')
if __name__ == '__main__':
    main()