把一直學不懂的各種大常數 \(o(n\log n)\) 的神奇多項式演算法總結一下……
證明什麼的比較簡略……
還有我今天才知道預處理一下單位根會快很多 \(qwq\)
最沒用的乙個
首先我們能寫出乙個 \(o(n^2)\) 的暴力 這個你都不會就可以退役了(某位dalao題解中的)
要確定乙個多項式,我們發現只要代 \(f(1),f(2),f(3),...,f(n+m)\) 然後暴力插值就可以了。
還是不行。但是聰明的數學家們發現單位根有分治的特性,然後 \(fft\) 就發明出來了。
\(fft\) 分兩步,一步 \(dft\),一步 \(idft\)。
\(complex:\)
struct complex
};complex operator + (complex a,complex b)
complex operator - (complex a,complex b)
complex operator * (complex a,complex b)
\(fft:\)
inline void fft(complex *f,int op)
inline int sub(int x,int y)
inline int mul(int x,int y)
inline void calcrev(int lim)
inline int fpow(int a,int b)
for(int len=1,l=0;len<=mod;len<<=1,l++)
\(ntt:\)
inline void ntt(int *f,int n,int op))\)
\(f(x)*h(x)\equiv 1(mod\ x^n)\)
\(g(x)-h(x)\equiv 0(mod\ x^)\)
\((g(x)-h(x))^2\equiv 0(mod\ x^n)\)
\(g^2(x)-2*g(x)*h(x)+h^2(x)\equiv 0(mod\ x^n)\)
\(f(x)*g^2(x)-2*g(x)*f(x)*h(x)+f(x)*h^2(x)\equiv 0(mod\ x^n)\)
\(f(x)*g^2(x)-2*g(x)+h(x)\equiv 0(mod\ x^n)\)
\(h(x)=2*g(x)-f(x)*g^2(x)(mod\ x^n)\)
\(inv:\)
inline void inv(int *a,int *b,int n)q(\frac 1x)*x^mg(\frac 1x)+x^*x^*r(\frac 1x)\)
\(f_r(x)=q_r(x)*g_r(x)+x^*r_r(x)\)
\(f_r(x)=q_r(x)*g_r(x)(mod\ x^)\)
然後到這裡 \(q_r(x)\) 就可以求出來了,求出來由 \(r(x)=f(x)-q(x)*g(x)\) 求出 \(r(x)\)
\(div:\)
inline void div(int *a,int *b,int *c,int n,int m))\)
\(g(x)\equiv h(x)(mod\ x^)\)
\(g(x)-h(x)\equiv 0(mod\ x^)\)
\((g(x)-h(x))^2\equiv 0(mod\ x^)\)
\(g^2(x)-2h(x)*g(x)+h^2(x)\equiv 0(mod\ x^n)\)
\(f(x)-2h(x)*g(x)+h^2(x)\equiv 0(mod\ x^n)\)
\(g(x)=\large \frac \)
\(sqrt:\)
inline void sqrt(int *a,int *b,int n)^(x-a_i)\),類似分治 \(fft\) 的思路,但是要用到多項式取模。
我們用類似線段樹的方式存下所有多項式。
\(build+eval:\)
void build(int *a,int l,int r,int x)
int mid=(l+r)>>1;
build(a,l,mid,x<<1);
build(a,mid+1,r,x<<1|1);
int n=p[x<<1].size(),m=p[x<<1|1].size();
static int a[maxn],b[maxn],c[maxn];
for(int i=0;i>1,m=p[x].size();
static int a[maxn];int *b=q[dep];
for(int i=0;i咕咕咕。
\(calc+solve:\)
void calc(int *a,int *b,int dep,int l,int r,int x)
int mid=(l+r)>>1,n=p[x<<1].size(),m=p[x<<1|1].size();
static int a[maxn],c[maxn];int *b=q[dep];
calc(a,b,dep+1,l,mid,x<<1);
for(int i=0;i前五個是 \(o(n\log n)\) 的,後面三個是 \(o(n\log^2 n)\) 的。
\(upd:\) 居然忘了多項式 \(ln\) 和 \(exp\)。。。
拆係數 \(fft\),實際使用比三模數要快。不過我的 \(mtt\) 必須要開 \(long\ double\) 是什麼鬼啊。。。
\(mtt:\)
inline void mul(int *a,int *b,int *c,int n,int m)
fft(a,lim,1);fft(b,lim,1);fft(c,lim,1);fft(d,lim,1);
complex tmp;
for(int i=0;ifft(a,lim,-1);fft(b,lim,-1);fft(c,lim,-1);
for(int i=0;i}
學習筆記 多項式
給你n個點 x 1,y 1 x 2,y 2 求乙個n 1次的多項式 f x 求 f k 我們可以認為 f x f 1 x f 2 x f x 其中 f i x i y i 且 forall j neq i,f i x j 0 也就是說乙個點 x i 只在乙個函式中為 y i 其他函式中均為0 換言之...
多項式學習筆記
太菜了並不是很理解多項式,簡單記錄一下,緩慢更新吧 有問題問快速航 首先我們要求的柿子長這樣 c k sum a i b j 大概思路 先把兩個多項式轉成點值 dft 再把兩個多項式的點值乘在一起,把新的點值轉成多項式 idft 即可 首先要了解複數的運算 a b i c d i a c b d i...
多項式 學習筆記
已知兩個多項式的係數表示式,求其乘積的係數表示式。c n sum limits a ib 係數表示式逐項相乘,複雜度 o n 2 而點值表示式相乘複雜度為 o n 因此我們要快速地將兩個多項式轉化為點值表示式,完成點值表示式的乘法,然後轉為係數表示式得到結果。表示式轉換的過程分別是離散傅利葉變換 d...