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
))可以看到因為f
ff陣列是要求出來的,所以不能直接用fft
fftff
t或者ntt
nttnt
t,暴力是n
2n^2
n2的,如果單用fft
fftff
t是n2lo
gn
n^2logn
n2logn
的,還沒有暴力優秀。
於是就有了分治fft
fftff
t如果已經知道了f(l
)f(l)
f(l)
~f (m
id
)f(mid)
f(mid)
,那麼對於後半部分的貢獻是:已知f(x
)f(x)
f(x)
,則對f(i
)f(i)
f(i)
有f (i
−j)×
g(j)
[i−j
=x
]f(i-j)\times g(j)\ [i-j=x]
f(i−j)
×g(j
)[i−
j=x]
的貢獻,所以可以進行構造:
設a (i
)=f(
i+l)
i∈[0
,mid
−l],
b(i)
=g(i
+1)i
∈[0,
r−l−
1]
a(i)=f(i+l)\ i\in[0,mid-l],b(i)=g(i+1)\ i\in[0,r-l-1]
a(i)=f
(i+l
)i∈[
0,mi
d−l]
,b(i
)=g(
i+1)
i∈[0
,r−l
−1]然後進行ntt
nttnt
t,再把f(m
id+1
)f(mid+1)
f(mid+
1)~f (r
)f(r)
f(r)
的貢獻加上,對f(i
)f(i)
f(i)
的貢獻就是a(i
−l−1
)a(i-l-1)
a(i−l−
1)
#include
#include
#include
#include
#include
#define maxn 400005
#define ll long long
using
namespace std;
const
int mod=
998244353
;inline
intrd()
int n,limit,lim,f[maxn]
,g[maxn]
,a[maxn]
,b[maxn]
,rev[maxn]
;inline
intqpow
(int x,
int k)
return ret%mod;
}inline
void
ntt(
int*f,
int type)}}
if(type==-1
)}inline
void
work
(int
*a,int
*b)void
cdqfft
(int l,
int r)
intmain()
話說還有更優的演算法那就是多項式求逆不過現在窩還沒學等學了再說qwq
qwqqw
q ( up
d:原來
腦子一熱
寫成了矩
陣求逆小
夥伴們千
萬別被誤
導了啊q
wq
(upd:原來腦子一熱寫成了矩陣求逆小夥伴們千萬別被誤導了啊qwq
(upd:原
來腦子一
熱寫成了
矩陣求逆
小夥伴們
千萬別被
誤導了啊
qwq以及現在學了多項式求逆了但分治fft 就不錯啊
luogu 模板 分治 FFT
題目背景有提示啊。給定乙個陣列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 ...
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值會依賴與...