問題
思考過程
長ければ長いほど、とりあえず条件は満たせるので、どこまで「短くできるか」ということを考える。となると、おそらく各区間の端っこの部分で、ここでどうなるかを考える。
最初に、区間の「の最大値」と「の最小値」を考えてみる。が、いまいちピンとこない(入力例1だとなにか言えそうだが、入力例3だとよくわからない)。「の最大値」と「の最小値」のどちらが大きいかは入力によりそうなので、この値からなにかいうのは難しそう。
では端からどちらか選んでみることを考えてみるとどうか?
入力例3の1つ目(と2つ目)の区間で "1" を選ぶとする。すると、どこまで長くしなければいいか考えてみると、「1よりも大きい中で最大の区間の端のどちらか」である。この場合は "5" になる。ということで、"1"始まりの良い数列の長さは、長さが5から9まで1つづつある。
つぎに、5つ目の区間で "2"を選ぶ、つまり始まりを"2"にすることを考えると、2つ目の区間では"1"が選ばれなかったため、 "7"を選ぶ必要がある。つまり、最低でも"7"以上まで伸ばす必要がある。
こう考えていくと、「良い数列の左端を固定したとき、選ぶ必要のある数の中での最大値が、右端になりうる最小値」として考えられる。ある区間については、最初はが選ばれる候補であるが、良い数列の左端の数字がを超えてしまった場合はが候補になる。最小のよりの大きい数が左端の数字になったら打ち切る。
ということで、候補の数は最大で 個で、入れ替えが生じるものに対して最大値が取れればいいので、sorted_setを使えば高速で判定が可能になる。Pythonであれば、tatyamさんのSortedSetを使って、追加・削除で、最大値の取得に でできるので、全体として計算量は でできる。
あと、作れる長さを範囲で足し算するのは、imos法*1を使うことで でできる。
ACコード
*1:厳密にはimos法とは言わないという話を聞いたような気がする(うろ覚え)