1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

解きます

解く

答えを$a_N$と書くことにします. この問題の順列が「条件を満たさない」というのは「真接頭辞が順列になるものがある」, 更に「真接頭辞が条件を満たす順列になるものがある」と言い換えられます.
長さ$N$の順列は$N!$個あるので, この言い換えを基に,
$$a_N = N! - \sum_{k=1}^{N-1} a_k(N-k)!$$
のような漸化式が立ちます. これをFPSにしましょう.

$$\begin{align}
f &= \sum_{i=1}^\infty a_i x^i \\
&= \sum_{i=1}^\infty x^i\left(i!-\sum_{j=1}^{i-1} a_j(i-j)!\right) \\
&= \sum_{i=1}^\infty x^ii! - \sum_{j=1}^\infty a_j\sum_{i=j+1}^\infty x^i(i-j)! \\
&= \sum_{i=1}^\infty x^ii! - \sum_{j=1}^\infty a_jx^j\sum_{i=1}^\infty x^ii! \\
&= \sum_{i=1}^\infty x^ii! - f\sum_{i=1}^\infty x^ii! \\
\end{align}$$
$g=\sum_{i=1}^\infty x^ii!$と置いて, 求めるべきものは
$$\begin{align}
f &= g - f g \\
\left(1+g\right)f &= g \\
f &= \frac g{1+g} \\
&= 1-\frac 1{1+g} \\
\end{align}$$
と分かりました. 昨日と同じニュートン法で$O\left(N\log N\right)$で解けますね.

use ac_library::*;
use proconio::*;

type Mint = ModInt998244353;

fn main() {
    input! {
        n: usize,
    }

    // h = 1+g
    let mut h = vec![Mint::raw(1)];
    for i in 1..(n + 1).next_power_of_two() {
        h.push(h[i - 1] * i);
    }

    // ニュートン法で逆数を求める
    let mut f = vec![Mint::raw(1)];
    while f.len() < h.len() {
        let m = convolution(&f, &f);
        let m = convolution(&m, &h[..f.len() * 2]);
        f.extend((0..f.len()).map(|_| Mint::raw(0)));
        for i in 0..f.len() {
            f[i] = f[i] * 2 - m[i];
        }
    }
    // 1から引いたもの(n=0のケースは与えられないので単に符号反転すればいい)が答え
    println!("{}", -f[n]);
}

提出(108 ms):

終わり

ここの$g$は$x$が実数なら$x=0$のとき以外発散しちゃうんですが, こういうの考えてもいいんですね
以上です

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?