luogu 模板 分治 FFT

2021-09-25 06:01:48 字數 3456 閱讀 9036

題目背景有提示啊。

給定乙個陣列f

ff,求gi=

∑j=1

igi−

jf

jg_i=\sum_^g_f_j

gi​=∑j

=1i​

gi−j

​fj​

。考慮寫出g

gg的生成函式。

g (x

)=g(

x)f(

x)+g

(0)g

(x)=

g(x)

f(x)

+1g(

x)=1

1−f(

x)

\beging(x)&=g(x)f(x)+g(0)\\ g(x)&=g(x)f(x)+1\\ g(x)&=\frac\end

g(x)g(

x)g(

x)​=

g(x)

f(x)

+g(0

)=g(

x)f(

x)+1

=1−f

(x)1

​​考慮只有0

00至n−1

n-1n−

1次數項有用,因此有:

g (x

)≡11

−f(x

)(mo

dxn)

g(x)≡\frac(\mod x^n)

g(x)≡1

−f(x

)1​(

modx

n)多項式求逆即可。

時間複雜度:θ(n

log⁡n)

\theta(n\log n)

θ(nlogn)

#include

#include

#include

#define ll long long

const ll mod=

998244353

,g=3

,inv_g=

332748118

;using

namespace std;

int a[

1000010

],b[

1000010

],f[

1000010

],g[

1000010];

int limit,n,l,r[

1000010];

intdg

(int x,

int k)

intinv

(int x)

void

init

(int n)

void

ntt(

int*now,

int limit,

int op)}}

}void

dft(

int*f,

int n,

int limit)

void

poly_inv

(int

*f,int

*g,int n)

poly_inv

(f,g,

(n+1

)>>1)

;init

(n);

memset

(a,0

,sizeof

(a))

;memset

(b,0

,sizeof

(b))

;for

(int i=

0;i) a[i]

=f[i]

,b[i]

=g[i]

;ntt

(a,limit,1)

,ntt

(b,limit,1)

;for

(int i=

0;i) b[i]

=(ll)b[i]*(

(2ll

-(ll)a[i]

*b[i]

%mod+mod)

%mod)

%mod;

dft(b,n,limit)

;for

(int i=

0;i) g[i]

=b[i];}

intmain()

poly_inv

(f,g,n)

;for

(int i=

0;i)printf

("%d "

,g[i]);

}

不得不學正統的分治ntt

\text

ntt了。

考慮分治解決這件事情。

就是對於當前區間[l,

r]

[l,r]

[l,r

],我們分成[l,

mid]

,(mi

d,r]

[l,mid],(mid,r]

[l,mid

],(m

id,r

]來完成。

那麼中途我們需要計算[l,

mid]

[l,mid]

[l,mid

]對(mid

,r

](mid,r]

(mid,r

]的貢獻,容易發現等號右邊是乙個卷積的形式,ntt

\text

ntt優化即可。

時間複雜度:θ(n

log⁡2n

)\theta(n\log^2 n)

θ(nlog2n

)。

#include

#include

#include

#define ll long long

const ll mod=

998244353

,g=3

,inv_g=

332748118

;using

namespace std;

int a[

1000010

],b[

1000010

],f[

1000010

],g[

1000010];

int limit,n,l,r[

1000010];

intdg

(int x,

int k)

intinv

(int x)

void

init

(int n)

void

ntt(

int*now,

int limit,

int op)}}

}void

dft(

int*f,

int n,

int limit)

void

poly_cdq

(int

*f,int

*g,int l,

int r)

intmain()

模板 分治FFT

luogu4721一道模板題 前置知識 fft ntt cdq cdqcd q分治 雖然本人覺得和cdq cdqcd q沒啥關係,應該只用了分治思想 用來解決這樣的式子 f i j 1i f i j g j f i sum i f i j times g j f i j 1i f i j g j 可...

luoguP4721 模板 分治 FFT

luogu 給定長度為 n 1 的陣列 g 1 g 2 g n 1 求 f 0 f 1 f n 1 其中 f i sum if i j g j 邊界為 f 0 1 答案模 998244353 分治 ntt。跑900 ms 其實limit只要設到區間長度就可以了,其他的是用不到的。對前半部分也沒得影響...

P4721 模板 分治 FFT

雖然說是fft但是還是寫了一發ntt 笑 然後忘了idft之後要除個n懵逼了好久 以及遞迴的時候忘了邊界無限re 樸素演算法 分治fft 考慮到題目要求求這樣的乙個式子 f x sigma f g 我們可以按定義暴力,然後再鬆式卡常 不是 我們可以發現它長得像乙個卷積一樣,但是因為後面的f值會依賴與...