自分だけ解けない問題
この記事は、Codeforces Global Round 25 F. Inversion Composition の解き方を提案したものです。自分は解説を見て考えただけです。
「自分だけ解けない問題」と自分が言う問題たちは、解説を見たり、ヒントを得て解法を思いついたりしても必ずバグり、通すために時間がかかってしまうという傾向にあります。この問題も何も分からず、解説を見た上でさえ6時間以上ACできませんでした。
「自分だけ解けない問題」はそれにも拘らずやってきます。このACの苦戦を「次に向けて反省せよ」とのメッセージと解釈し、どういうふうに解けばよいのかを整理してみました。
PART 1
まずは軽く実験してみると、 かつ だったら問題文の条件を満たすような が必ず存在すると予想できます。これは正しい(ことが後々証明できる)ので、今後はこの条件を仮定します。
ただし、ここから構築方法を当てるのは難しいです。
PART 2
、すなわち とします。 と がどのような関係で動くのかは想像しにくいです。そこで、 と の転倒数の和がどのように動くのかに注目します。転倒数の定義に注目します。
の転倒数は かつ を満たす組の個数、すなわち かつ を満たす組の個数です。
の転倒数は かつ を満たす組の個数です。ここで、転倒数はどのような順番で計算してもよいです。なので、 の転倒数は 「 ( とは限らない )かつ を満たす組の個数」に言い換えられます。
これらは似た形をしていますが、感覚的に、 かつ のときは による と による は打ち消し合い、 かつ のときは による と による はマッチして 倍に増幅するように思えます。定常波における「節」と「腹」を思い出します。
詳しく書いてみると:
- かつ なら
- なら において にちょうど だけ寄与する
- なら において に寄与しない
- なら において にちょうど だけ寄与する
- なら において に寄与しない
- かつ なら
- なら において に寄与しない
- なら において にちょうど だけ寄与する
- なら において にちょうど だけ寄与する
- なら において に寄与しない
となるので、
- かつ なら、
- すなわち なら にちょうど だけ寄与する
- すなわち なら に寄与しない
- かつ なら、この組は に必ずちょうど だけ寄与する。
と分かります。
後者は に関係なくちょうど だけ寄与するので、この組については何も気にしなくてよいことが分かります。しかも、「 かつ 」なので合計すると になります。また、 かつ かつ のときは に何も寄与しません。
よって、問題は「 かつ かつ となる個数が になるような順列 を作る」ことに帰着されます。
PART 3
改めて、 とおきます。解くべき問題は、
かつ かつ となる個数(これをスコアということにします)が になるような順列 を作る
です。明らかに のときはスコア 、 のときはスコア最大です。
スコアを にぐっと近づけてから調整することを考えます。ある があって、 のときスコアは 以下、 のときスコアは 以上となります。この を固定します。
としておいて、ここから調整します。これはスコア 以上なので、スコア にするには、 個ずつ かつ かつ となる個数を減らせばよいです。つまり、いままで であったものを に変えればよいです。
ここで、
- スコア 以下であるところの の左から 番目の位置にある に注目すると、 について になっている
- スコア 以上であるところの の左から 番目の位置にある に注目すると、 について になっている
ことが分かります。さらに、この つの順列について「 が に関係しない組 についての の大小関係は一緒」ということも分かります。
左から 番目の位置にある値を 個ずつ上げていく操作をする(ただし他の組の大小関係は変わらないようにする)と、 以上だったスコアがどんどん下がります。
操作 回ごとに の組の大小関係が つだけ 「」 から 「」 に変わるのでスコアは または 減ります。 を まで上げるとスコアが 以下になることは分かっているので、どこかで必ず になります。ここでストップすればよいです。
つまり、完成品は、ある が存在して、 となります。 は左から 番目の位置にあります。
PART 4
PART 3 の実装をします。まず を決めたいと思います。 のスコアは、「 かつ の個数」です。
よって、BIT かセグメント木などを使うと、転倒数と同じように について のスコアを求めることができます。スコアが 以上になる最小の を採用すればよいです。
次は調整ですが、 の順に、 だったものを に解消していきます。もし だったらスコアが 下がり、そうではなかったらスコアは下がりません。スコアが になったらストップし、 を用いて を求めて出力すればよいです。
反省
正確に詰めるのも思いつくのも難しいです。転倒数はどういう順番でも数え上げてよく、さらに各組 たちが転倒数に寄与していく、という見方は頻出だから、上に書いた考察は自然なのかもしれないと思いました。(もしくは、これが自然になるように頑張る)