より、 つのクエリ処理にかけてはいけないと分かる。
それぞれにかかるスワップの最小回数から、自身がスワップされる回数も求めることができる。
つの紐を反転させるのに必要なスワップの回数は、 回。
つの紐の時、題名通り三つ編みを実装しよう。
がある。これを にしたい時、
これで、 回の操作でできることがわかる。これが最短だということの証明は、転倒数を用いて行うことができる。
転倒数:
転倒(数学) - wikipedia
転倒数の概要とバブルソート・BITによる解法 | アウトプット雑記
BITで転倒数を求める - Qiita
などを参考にしてください。
この「三つ編み方式」では本の紐がある時全ての紐について 回スワップを行うことで高速に反転を行っている。
この問題の条件下で、最短の操作回数で操作を行うことと、すべての数に対してそれぞれ紐の数回スワップを行うことが同値だということは証明できる。
writerによる証明:数学的帰納法を用いた証明
個の数を題意における最小のスワップ回数反転させるときのそれぞれの数が移動する回数
と置く
の時、例えば を反転させるのには と を 回スワップさせれば良い
この時に はそれぞれ 回ずつスワップされているので成り立つ
のとき、これを証明した
の時、先に個の数を反転させてから、最後に 個目の数を反対側の端に持っていくことを考える
先に行う操作で、個の数は 回スワップされている。
最後の操作で、端にある数 は、反対側まで移動するのに回スワップを行わなければいけない。またこのとき、他の数は 回ずつスワップされている。
(これが最短なのは上に書いてあるはずの転倒数を用いると証明できる)
よって の時、全ての数は回スワップされている。
証明終わり
よって、反転時にかかるコストはのそれぞれの数となる。
この区間和は、累積和を用いることでで求めることができる。
計算量はです。
実装例(c++):こちら