ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

ABC072 D - Derangement

問題
提出コード

解法

p_i = iとなっている部分は、p_{i-1}もしくはp_{i+1}スワップをすることで、p_iは条件を満たすことができます。
このとき、実はスワップ先のp_{i-1}もしくはp_{i+1}も条件を必ず見たします。なぜなら、この数列は順列なので、p_i=iだった場合は、p_{i-1}もしくはp_{i+1}iとなり、中身の値がpの添え字と異なるからです。
このことを利用すると、前から順番に見ていき、p_i = iが存在した部分はp_{i+1}スワップする、という操作を繰り返すだけでよいことがわかります。
ただし、p_N = Nだった場合のみ注意が必要で、この場合はp_{N-1}スワップをすれば十分です(この操作により、前の方の最善手が変わることはありません)。