🚧 This website is under construction. 🚧
AtCoder
ABC
174
F

ABC174 F - Range Set Query

https://atcoder.jp/contests/abc174/tasks/abc174_f (opens in a new tab)
水色上位。データ構造。

クエリに対してオフラインに回答することを考える。 まずはスケジューリング問題と同様にまずはクエリを右端の値でソートしておき、この順番に回答する。

左端のボールから順番に見ていくが、その時同じ色のボールは一番右側に位置するもののみ管理する。(区間の右端でソートしており、区間の左端のインデックスより大きいものにのみ興味があるため)。各色のボールにインデックスに対応する部分にフラグを立てておけば、BIT により区間和を計算することによって各クエリに回答できる。

import sys
 
input = sys.stdin.readline
 
 
def add(p, x):
    p += 1
    while p <= n:
        bit[p - 1] += x
        p += p & -p
 
 
def sum(left, right):
    return _sum(right) - _sum(left)
 
 
def _sum(r):
    s = 0
    while r > 0:
        s += bit[r - 1]
        r -= r & -r
 
    return s
 
 
n, q = map(int, input().split())
c = list(map(lambda x: int(x) - 1, input().split()))
lr = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(q)]
 
res = [None] * q
 
# balls[i] := 最も右端に位置する色iのボールのインデックス
balls = [None] * n
 
# bit[i] := インデックスiに条件を満たすボールが存在する
bit = [0] * n
 
pre_r = 0
for i in sorted(range(q), key=lambda i: lr[i][1]):
    l, r = lr[i]
    for j in range(pre_r, r + 1):
        if not balls[c[j]] is None:
            add(balls[c[j]], -1)
        balls[c[j]] = j
        add(balls[c[j]], 1)
    res[i] = sum(l, r + 1)
    pre_r = r
 
print(*res)
 

定数倍との勝負であり、何回か提出する必要がある。