其他多項式演算法傳送門:
[多項式演算法](part 1)fft 快速傅利葉變換 學習筆記
[多項式演算法](part 2)ntt 快速數論變換 學習筆記
[多項式演算法](part 3)mtt 任意模數fft/ntt 學習筆記
[多項式演算法](part 4)fwt 快速沃爾什變換 學習筆記
分治fft是一種基於cdq分治(不是很懂和cdq有什麼關係)的演算法,主要用於在\(o(nlog^2n)\)的時間複雜度內計算以下內容:
給定數列\(g_1\sim g_\),求\(f_0\sim f_\),其中\(f_i\)滿足
\[f_0=1\\
f_i=\sum_^jf_\times g_j
\]我們可以借鑑分治的思想,對於當前的\(f_l\sim f_r\),設\(mid=\lfloor\frac\rfloor\)
先遞迴計算\(f_l\sim f_\),接著考慮前半部分對後面的貢獻。
設對\(f_x(mid+1\le x\le r)\)的貢獻為\(w_x\),則有
\[w_x=\sum_^f_i\times g_
\]為了下面推導方便,把範圍擴大,設\(f_i=0(mid+1\le i\le r)\):
\[w_x=\sum_^f_i\times g_\\
w_x=\sum_^f_\times g_
\]此時設\(a_i=f_,b_i=g_\),則有:
\[w_x=\sum_^a_i\times b_
\]那麼就會發現這是乙個卷積的形式,使用fft計算即可。
好像挺簡單的?以前都沒敢學來著
例題: luogu p4721 【模板】分治 fft
這裡我使用ntt來實現演算法,當然使用fft也是沒有問題的。
加了io優化,**可能有點亂?
時間複雜度 \(o(nlog^2n)\)
空間複雜度 \(o(n)\)
// luogu-judger-enable-o2
#include #include #include #include #include #define rint register int
typedef long long ll;
//----- io optimize -----
#define getchar (p1==p2&&(p2=(p1=in)+fread(in,1,1<<20,stdin),p1==p2)?eof:*p1++)
char in[1<<20],*p1=in,*p2=in,ch,out[1<<21],*outp=out,st[15],*tp=st;
inline int getint(register int x=0)
inline void putint(int x,char c)
const int p=998244353,g1=3,g2=(p+1)/3;//g2為1/3 mod p
inline int add(int a,int b)
inline ll pow(ll a,ll b)
namespace poly
}int n,f[1<<18],g[1<<18];
int main()
{ n=getint(),f[0]=1;
for(rint i=1;i分治fft還是比較簡單易懂的。
其中還有乙個小優化:對於遞迴到範圍較小的序列,直接暴力卷積,常數更小。
多項式演算法 Part 5 分治FFT 學習筆記
其他多項式演算法傳送門 多項式演算法 part 1 fft 快速傅利葉變換 學習筆記 多項式演算法 part 2 ntt 快速數論變換 學習筆記 多項式演算法 part 3 mtt 任意模數fft ntt 學習筆記 多項式演算法 part 4 fwt 快速沃爾什變換 學習筆記 分治fft是一種基於c...
我的演算法筆記(5)分治(1)
乙個臨時陣列 intmin int x,int y void merge int a,int s,int m,int e,int b 只要有乙個陣列的數全部都排完了,那麼我就可以吧另乙個陣列剩下的全部數就都放在臨時陣列裡了 while x1 m b x a x1 while x2 e b x a x...
作業5 分治演算法之最近對問題
最近對問題 令p為笛卡爾平面上n 1個點構成的集合。簡單起見,假設集合中每個點都不一樣。我們還假設這些點是按照其x周座標公升序排列的。為了更加方便,我們還按照點的y軸座標在另乙個列表中進行公升序排列,分別記為px,py。當2 n 3時,通過蠻力求解出d。當n 3時,可以利用點集在方向上的中位數mid...