0
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?

More than 1 year has passed since last update.

初心者用 形式的冪級数の逆元の定数倍高速化

Posted at

はじめに

前回の記事 で形式的冪級数の逆元を求める式を書いたのですが, $O(n\log n)$ とはいってもなかなかに定数倍が重いです

NTT-friendly な mod で計算する場合は, もっと定数倍が高速な方法が知られています

inv を求める方法

exp を求める方法

が公開されていました

ところで, 僕はこれを全く理解していません

僕のような初心者には厳しいので, 軽い実装でそこそこ高速になる方法を紹介します (と思ったんですが, 一個目の記事に載っていました...)

本文

前回

g_{n + 1} = 2g_n - f g_n^2

というような漸化式で計算していけばいい と書きましたが, $f g_n^2$ の計算が重いです

そこで, ここを少し速くすることを考えましょう

$g_n^2$ の計算をするとき, まず DFT をして要素ごとに二乗して IDFT をしていると思います

ここで, DFT をして要素ごとに二乗してそのままにしてみましょう

IDFT をしてもどうせ $f$ をかけるのでまた DFT することになるためです

つまり,

  1. $f, g_n$ の DFT を計算する
  2. $f g_n^2$ を DFT した先で要素ごとに計算する
  3. 最後に一回だけ IDFT する

とすることで, 回数を減らします

ここで注意なのが, DFT するときに元の数列の長さを $N = 2^n$ とすると普段は長さ $2N$ で計算すればよかったですが今回は $4N$ 必要だということです

三つかけるので補間のために最終的な次数の分計算しないといけないわけですね

これによってどれくらい速くなるのかですが, もともとは

長さ $2N$ の DFT 二回 $+$ 長さ $2N$ の IDFT 一回
$+$ 長さ $4N$ の DFT 二回 $+$ 長さ $4N$ の IDFT 一回

だったのが

長さ $4N$ の DFT 二回 $+$ 長さ $4N$ の IDFT 一回

だけで済みます

うれしい!

終わりに

実装量のわりに結構速くなるのでおすすめです

とはいえ 循環をうまく利用する? やつもいつかは理解しないとね...

0
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
0
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?