問題. What Goes Up Must Come Down
非負整数列 が与えられる.
の隣り合う2要素を交換するという操作を繰り返して
を山型にしたい.ただし,数列
が山型であるとは,ある要素
が存在して,
となることである.数列
を山型にするための交換回数の最小値を求めよ.
制約: ,
解法. BIT
まず初めの観察として, の最小値で最も端にある要素
に着目したとき,
の任意の操作後の山型な数列に対して,
はその数列の左端か右端のどちらかにある.また,操作後の最適な山型な数列に対しては,
は最も近い左端か右端になることが分かる.この操作によって,
以外の2要素間の位置関係は保たれており,これを再帰的に行うと答えが求まる.すなわち,操作済みではない部分列に対して,その最小の要素で最も部分列の端にあるものを近い端に移動するということを再帰的に行う.
このアルゴリズムは Binary Indexed Tree (BIT) を用いて愚直に計算すると で計算することができるが,この再帰的な移動で着目している要素が何かを考えるとより高速に計算できる.各
に対して,上で再帰的に行ったときの操作回数は,
上で
より左にあって
よりも大きい値の数と,
より右にあって
より大きい値の数の最小値と等しくなる.
より左にあって
よりも大きい値の数は ,BIT
bit[i] の引数 を
の要素の値として,BIT の値
bit[i] を よりも左にあって値が
となる
の要素数として,左から更新しながら計算することによって求めることができる.同様に,右にある値も右から更新しながら計算できる.よって,この問題では
の上限と
の上限が等しいので,全体で
時間で答えを求めることができる.
計算時間:
まとめ
初め最小値ではなく最大値を考えてムムッとなっていた.