任意模數快速傅利葉變換的兩種方法

2021-08-28 12:37:31 字數 3276 閱讀 8339

對於初值在p

pp範圍內的序列a(x

)和b(

x)

a(x) 和b(x)

a(x)和b

(x),一次卷積之後大小不超過np2

np^2

np2。找三個數論模數分別ntt之後,用中國剩餘定理合併。不用大數或者__int128,可以參考下面的做法。

板子題:p4245 【模板】任意模數ntt

code:

// luogu-judger-enable-o2

#include

using namespace std;

typedef

long

long ll;

const

int maxn =

2e6+

10, g =3;

const

double eps =

1e-3

;int mod;

int rev[maxn]

;ll qmul

(ll a, ll b, ll c)

inline ll qpow

(ll a,ll b,ll p)

const

int m1 =

998244353

,m2 =

1004535809

,m3 =

469762049

;const ll _m =

(ll)m1 * m2;

const

int inv1 =

qpow

(m1 % m2,m2-

2,m2)

;const

int inv2 =

qpow

(m2 % m1,m1-

2,m1)

;const

int inv12 =

qpow

(_m % m3,m3-

2,m3)

;ll crt

(ll a1, ll a2, ll a3)

struct ntt

void

dft(

int* a,

int n,

int r)if(

!r)for

(int i =

0,inv =

qpow

(n,p-

2,p)

;i) a[i]

=1ll

* a[i]

* inv % p;

}}ntt[3]

;int a[maxn]

,b[maxn]

,c[maxn]

,d[maxn]

,tmp[3]

[maxn]

;int

main()

ntt[i]

.dft

(tmp[i]

,n,0);

}for

(int i =

0;i< n + m +

1;i++

)return0;

}

又稱mtt 。

大概就是把係數拆成f(x

)=p∗

k(x)

+r(x

)f(x) = \sqrt*k(x)+r(x)

f(x)=p

​∗k(

x)+r

(x)的形式,然後再還原回去。樸素的版本一共需要7次dft

dftdf

t。卷積之後資料在npnp

np級別,為避免精度誤差,需要用到lon

gdou

bl

elong~double

longdo

uble

,並預處理單位方根。

板子題:p4245 【模板】任意模數ntt

code:不知道為什麼跑得比三模數ntt慢啊

// luogu-judger-enable-o2

#include

#include

#include

#include

#include

#include

using namespace std;

const

int maxn =

6e5+10;

const

long

double pi =

acos((

long

double)-

1.0)

;const

double eps =

1e-3

;typedef

long

long ll;

int mod,m;

struct cp

cp operator +

(cp x)

cp operator -

(cp x)

cp operator *

(cp x)

cp conj()

};int a[maxn]

,b[maxn]

,rev[maxn]

;cp a[maxn]

,b[maxn]

,k1[maxn]

,k2[maxn]

,r1[maxn]

,r2[maxn]

;cp s1[maxn]

,s2[maxn]

,s3[maxn]

,w[2

][maxn]

;int ans[maxn]

;void

get_wn

(int n)

}void

dft(cp* a,

int n,

int r)}if

(r ==0)

for(

int i =

0;i) a[i]

.r /

= n;

}void

mtt(cp* a,cp* b,

int n)

dft(k1,n,1)

;dft

(r1,n,1)

;dft

(k2,n,1)

;dft

(r2,n,1)

;for

(int i =

0;i)dft

(s1,n,0)

;dft

(s2,n,0)

;dft

(s3,n,0)

;for

(int i =

0;iintmain()

return0;

}

離散傅利葉變換的兩種實現方案

方案一 dftm sig ones 256,1 t 8 timeslice 8 timeslice f t nfft 256 sig cos 2 pi 1 t dft zeros nfft,nfft n 0 nfft 1 n的行向量,為1 n矩陣 k 0 nfft 1 k的行向量,為1 n矩陣 wn...

匯出離散傅利葉變換(DFT)的兩種方法

在這裡首先確定dft的物件為乙個有限長的離散非週期序列,這主要因為計算機處理的都是有限長的離散序列。如果你要處理的序列本身不是離散非週期的序列,可以通過擷取或者離散化等方法獲得所需的有限長的離散非週期序列。對於有限長的離散非週期序列存在兩種計算n點dft的方法,一種方法是先將其通過dtft獲得序列的...

兩種獲取Oracle Sequence的方法

前提 create table booking id integer not null,date made date,reserved until timestamp,price decimal 15,2 not null,purchase id integer,primary key id cre...