ABC478 D - Range Set Insertion Query

範囲集合挿入

考え方

愚直にやるのは簡単だが、計算量が $O(NQ\log Q)$ でTLE。
そこで高速化を考える。

最終的にどんな値が入っているかは要求されない。
そこで、集合に数を挿入するのではなく、挿入範囲に $1$ 個増えたという情報をもたせればよさそう。
これは $X$ の値がすべて異なる場合には有効な方法。
階差数列に情報をまとめてから累積和を利用することで $O(N+Q)$ で済む。

ただし、実際には同じ $X$ の値が同じ集合に入れられる場合がある。
この場合、重複カウントをしないようにする必要がある。
そこで、集合への挿入順を変えてしまう。

操作順序を変えても最終結果は変わらない。
そこで、最初に $X$ の値ごとに操作を分類してしまう。
さらに同じ $X$ の中で $L$ の値が小さい順にソートして、区間重複分は $L$ や $R$ を削り落とせばよい。
そうすれば、同じ $X$ があっても、前述の方法で解決できる。
ソートが必要な分、計算量は $O(N+Q\log Q)$ になる。

入力例1での動作

入力を受け取る。

n: 8
q: 5

queries:
2 5 1
1 4 2
7 8 1
3 6 3
2 5 2

まず、操作を $X$ ごとに分類する。

X=1: [2,5], [7,8]
X=2: [1,4], [2,5]
X=3: [3,6]

同じ $X$ の区間について、重複する部分をまとめる。
$X=2$ の $[1,4]$ と $[2,5]$ は重複しているので、$[1,5]$ にまとめられる。

したがって、各 $X$ について残る区間は次のようになる。

X=1: [2,5], [7,8]
X=2: [1,5]
X=3: [3,6]

この各区間について、その範囲の集合の要素数が $1$ 増えるものとして階差数列に記録する。
$1$ から $9$ までの位置について変化量を並べると、次のようになる。

位置:   1  2  3  4  5  6  7  8  9
変化量: 1  1  1  0  0 -2  0  0 -1

これを左から累積和すると、位置 $1$ から位置 $8$ までの値は次のようになる。

1 2 3 3 3 1 1 1

したがって、答えは 1 2 3 3 3 1 1 1 である。

注意点

特になし。

別解

特になし。