Chokudai Speed Run J-転倒数
転倒数、競プロに慣れてないと難しいと思いませんか?僕は難しいと思います。
リンク
https://atcoder.jp/contests/chokudai_S001/tasks/chokudai_S001_j
問題は次のようにいいかえられる。
問題概要
自然数と、を並び替えた配列が与えられる。
かつを満たすようなの組の数を求めよ。
方針・実装
各について、が条件を満たすようなの数を数える。であるから、を大きいほうからみてうまく数えられないかなーとなる。
*注意:説明では1-indexedにしていますが実際は0-indexedのほうがやりやすいと思います。
すでに見た数字がある要素の位置の集合をとするとき、次のようなことができればよい。(はの位置)
A.のうちより小さいものの数を求める。
B.にを挿入する。
そのために、セグ木を用いる。このデータ構造は、次のようなことが十分高速にできる。(正確には)
・ある要素に値を足す
・ある区間の和を求める
これを用いて
・の要素の和を求める
・番目の要素にを足す
と、それぞれA,Bに対応する。
例
の時の転倒数を求める。まず、大きい値から見た位置は]である。
になるようなの組は、もちろんである(で最大値をとるので)。
ここでセグ木のの位置にを加算する。セグ木の中身は、となっている。「次にが位置に入るときにあり得るようなの数」は、セグ木のの区間の和で求められる。この場合、の位置にが入れば答えは増えるし、の位置に入れば答えは増える。この場合はに入るので、のときのの個数はであり、セグ木の の位置に1を足す。
セグ木の中身はとなる。同様に、はの位置に入るのでのときのの個数はであり、セグ木のの位置にを足す。この時のセグ木の中身はとなる。最後にはの位置に入るのでのときのの個数はであり,セグ木の中身はとなる。求める答えはとなる。
コード
https://atcoder.jp/contests/chokudai_S001/submissions/9285044