辞書式順序の条件を無視すればただの区間スケジューリングなので、始点でソートして逆から貪欲に選んでいけば仕事の数の最大数が求まる。この際に得られた仕事の列が開始から
となっているとする。このとき、次の性質があることに注目する:
- 個の仕事をこなすためには、少なくともまでには始めなければならないし、までに始めれば個の仕事が可能である
- 個の仕事をこなすためには、少なくともまでには始めなければならないし、までに始めれば個の仕事が可能である
- ...
- 個の仕事をこなすためには、少なくともまでには始めなければならないし、までに始めれば個の仕事が可能である
これらの性質から、個の仕事からなる辞書順最小のスケジュールを構成する方法が従う:
- 個目の仕事はまでに終わるものならなんでも可能である。このうちインデックスが最小のものをとする。
- 個目の仕事は以降に始まってまでに終わるものならなんでも可能である。このうちインデックスが最小のものをとする。
- ...
- 個めの仕事は以降に始まるものならなんでも可能である。このうちインデックスが最小のものをとする。
こうして辞書順最小のスケジュールが得られた……わけだが、実際にこのスケジュールを求める手順がまだ明らかでない。
時間に始まってに終わる仕事のインデックスをとするとき(複数ある場合、インデックスが最小のもの以外は捨ててよい)、仕事は二次元空間上の点とみなせるので、上の性質をさらに言い換えられる:
- 上にある仕事についての最小値を求める。で最小になるとする。
- 上にある仕事についての最小値を求める。で最小になるとする。
- ...
- 上にある仕事についての最小値を求める。で最小になるとする。
ここまで整理すると、を乗せたrange treeで実行できる手順になっている。計算量は。
線形で求まるのは、手順を示されれば確かにとなるけどまったくわからなかった。
今出題されたら、もう少し制約が大きくなっては落ちる気がする。この方針のままでも、2D range tree + fractional cascading + 構築クエリのRMQでを1つにできそう? でも、そもそも平面走査的になんとかできないのかな。