F - You Got a Wrong Mail

2 secs 1024 MB
Yourein's icon Yourein

Editorial

ある数列PPについてPi=iP_i = i番目の人がもらった手紙の番号としたとき、この問題で求めるものは以下のように言い換えることができます。

  • 1つ以上のi (1iN)i \ (1 \le i \le N)についてPi=iP_i = iなる要素が存在する場合の数

これを直接考えるのはとても面倒なので余事象を考えてみます。

  • 数列PPの任意のiiについてPiiP_i \neq iが成り立つ場合の数

ここで「ii番目の手紙は人iiに届くはずだった。」ということから数列PPの中には1,2,...,N1, 2, ..., Nまでの数字が1つずつ存在することを考えると数列PPは順列であることがわかります。 したがって余事象は

  • 長さNNの順列PPにおける完全順列の個数

と言い換えることができます。

長さNNの完全順列の個数をana_nと置くとN=1N = 1のときa1=0a_1 = 0, N=2N = 2のときa2=1a_2 = 1, N3N \ge 3のときan=(n1)(an1+an2)a_n = (n-1)(a_{n-1}+a_{n-2})として求めることが可能です。(モンモール数)

また、長さNNの順列の総数はN!N!です。

したがって、求める答えはN!anN! - a_nです。 N!N!ana_nはそれぞれO(N)O(N)で求めることができるので、この問題をO(N)O(N)で解くことができました。

実装例(C++)

実装例(Python)