競技プログラミング用 知識集積所

ABC424F - Adding Chords

最終更新:

sport_programming

- view
管理者のみ編集可


問題


必要知識

B以下レベルの内容は省略

考え方

円環であることはあまり意味がないので、円を切り開いて、点1から点Nまでが一直線に並んでいるとして考える。
そして、点aと点bを結ぶことを、a<=x<=bの区間を┏━━━┓状の線で覆うと考える。
これでも線の高さをうまくとる(長いほど高くとる)前提でなら、問題は変わらない。

ここで、2つの隣接する点の上に何本横線が引かれるかを被覆数として考える。
既存の線に交差がない前提なら、引きたい線の交差本数は、新しく線を引きたい区間での「左端の被覆数+右端の被覆数-2*被覆数最小値」で求められる(ABC405F参照)。
特に、それが0であるかは、左端の被覆数、右側の被覆数、被覆数最小値が全て一致するかどうかで判定できる。
例えば入力例1の場合、2つ目の入力は、2-3の区間は被覆数1、6-7間の被覆数0なので、2-7間の最少被覆数0に両方一致にはなっておらず、1+0-2*0=1本交差している。

これを実装するには、以下の2つが必要。
  • 新しく引いた線の被覆数処理のため、区間加算
  • 被覆数最小値を出すため、区間最小値
これを高速に両方するには、lazy segment木※が最適である。

解答例


注意点


別解

タグ:

lazy segment木
ウィキ募集バナー