Official
E - 隣接スワップで転倒数を減らせ / Reduce Inversions with Adjacent Swaps Editorial
by
E - 隣接スワップで転倒数を減らせ / Reduce Inversions with Adjacent Swaps Editorial
by
physics0523
この問題は、 転倒数 を求めるのとそう変わらない手順で求めることができます。
\(P\) の転倒数を \(inv\) として、答えは \(\max(0,inv-K)\) です。なぜなら、一度の隣接 swap で転倒数を \(1\) 減らすことができ、また、 \(2\) 以上減らすことはできないからです。
少し丁寧に証明してみましょう。
転倒数は \(i<j\) かつ \(P_i > P_j\) を満たす \((i,j)\) の組の個数ですが、数列が昇順ソートされていない限り必ず \(P_i > P_{i+1}\) なる \(i\) を見つけることができます。ここを入れ替えることで転倒数を \(1\) 減らすことができます。
また、隣接 swap で前後関係が変わる要素の組は、隣接 swap で触った \(2\) つの要素の組以外に存在しないので、転倒数を \(2\) 以上減らすことはできません。
転倒数は Fenwick Tree を用いることで求められます。
実装例 (C++):
#include<bits/stdc++.h>
#include<atcoder/fenwicktree>
using namespace std;
using namespace atcoder;
using ll=long long;
int main(){
ll N,K;
cin >> N >> K;
fenwick_tree<ll> fw(N+5);
ll res=0;
for(ll i=0;i<N;i++){
ll P;
cin >> P;
res+=(i-fw.sum(0,P));
fw.add(P,1);
}
cout << max(0ll,res-K) << "\n";
return 0;
}
posted:
last update:
