Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ABC 041 D 徒競走

poyo
October 18, 2016

ABC 041 D 徒競走

poyo

October 18, 2016
Tweet

More Decks by poyo

Other Decks in Education

Transcript

  1. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ABC 041 D 徒競⾛ October 18, 2016
  2. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 問題概要 http://abc041.contest.atcoder.jp/tasks/abc041_d N ⽻のウサギさんたちがかけっこをするので、結果が何通りに なるのか求めよう。ただし、ウサギさん i よりウサギさん j の ほうが先にゴールしたという情報が M 個与えられるので、そ の情報全てに⽭盾することのないような結果が何通りになるの か求める。
  3. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 解説 この問題は公式の解説 http://abc041.contest.atcoder.jp/data/abc/041/ editorial.pdf がイケメンすぎるので、そちらを⾒よう。
  4. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . おわり おわり
  5. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . おまけ 問題に出てくるウサギさんたちを(可哀想だけど)頂点と呼び ます。また、ウサギさん情報のことを辺と呼びます1。まず、頂 点集合 S に対して f(S) を”題意を満たすような頂点 v ∈ S の並 び替え(並び⽅)の数”とします2。そうすると、最終的に求め なければいけないのはウサギさん全体の集合を U として f(U) となります。 1このスライドではできるだけウサギさんと呼びます。 2題意を満たすって⾔いたかっただけです。
  6. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 漸化式を⽴てよう 次に f(S) の漸化式を求めましょう。安易に考えると、S の中 で 1 位になれる可能性のあるウサギさんは多くても n(S) ⽻で す(つまり、S に属するすべてのウサギは 1 位になりうる) 。し かし、ウサギさん情報の存在により 1 位になりうるウサギさん は制限されます。たとえば Sab = {a, b} として a より b のほう が先にゴールしたという情報があるとします。このとき、S の 中で 1 位になりうるのは b のみです(結果は 1 位:b で 2 位:a しかあり得ない) 。したがって、f(S) は S から 1 位になりうる ウサギさん v ∈ S を除いたそれぞれの集合 S − {v} に対する f(S − {v}) の和となります3。 f(S) = ∑ v f(S − {v}) (v : 1 位になりうるウサギさん) 31 位のウサギさん v によって場合分けをすると考えます。
  7. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 初期条件は何だろう 漸化式を計算していくと、いずれ S の要素はからっぽになって しまいます(S = ϕ) 。ウサギさんが 1 ⽻もいないので、並び替 えの数は 1 通りです4。 f(ϕ) = 1 4???
  8. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 実装のテク 頂点集合 S を表現するのには 2 進数表記を使うと便利です。た とえば、N = 5 で S = {0, 1, 3} ならば 01011 と表します。つま り、頂点 i が S に属しているなら第 i ビットを 1 として、そう でないなら 0 とします。もちろん、U は全てのビットが 1 で ϕ は全てのビットが 0 で表されます。
  9. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 実装のテク 2 進数での表現を採⽤すると、実際のプログラムで頂点 i が S に属しているかを判定する部分は次のように書けます。 if((S>>i)&1){ ... } まず、S>>i でS を右にi ビットシフトしています。これによっ てS のi ビット⽬が⼀番下の桁になるので、(S>>i)&1 でi ビッ ト⽬が取り出せます。次のように書いても同じ動作をします5。 if(S&(1<<i)){ ... } 5たぶん
  10. . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . おわりに 解答例は http: //poyopoyoyon.hatenablog.com/entry/2016/10/18/184527