发现自己以前老是挑题做。。
看到多项式就跑了。。主要是以前学不会啊。。
现在要逼自己一把。。再一次开这个大坑
主要是卡在题上了
同时感觉自己智商有所提升。。理解起来也比以前好。。
以前看多项式求逆看来看去看不懂在干什么。。
操作可能不会一次学全。。需要的时候再点亮技能树再点吧
顺便这个是可以给我存模板的。。
当然,会附上学习资料。。
主要是为了以后忘了的时候看的。。这种东西当然忘得快
大部分题都可以在洛谷找到模板题。。
一些需要注意的点
基本上都是在
2
n
2^n
2n下操作的
一般都是4倍空间,巨大常数
泰勒展开式
一开始一直不敢看。。
知乎上写得挺好的
我个人喜欢第二个当然不是因为图
比较通用的形式是这个
但其实我们一般取的都是
x
0
=
0
x0=0
x0=0时的泰勒展开式,所以更多的时候,他的形式是这样的
一些需要知道,或者说做题的时候比较常用的泰勒展开式
别的大多数都可以在这些的基础上,通过换元或者相乘的方法弄出来
1
+
x
+
x
2
+
x
3
.
.
.
.
.
.
.
x
n
=
1
−
x
n
+
1
1
−
x
1+x+x^2+x^3.......x^n=\frac{1-x^{n+1}}{1-x}
1+x+x2+x3.......xn=1−x1−xn+1
其实就是等比数列求和,考虑级数收敛,当n趋近于无限大的时候就是
1
1
−
x
\frac{1}{1-x}
1−x1
1
+
x
+
x
2
2
!
+
x
3
3
!
+
x
4
4
!
+
.
.
.
.
.
.
+
x
n
n
!
+
.
.
.
.
=
e
x
1+x+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}+......+\frac{x^n}{n!}+....=e^x
1+x+2!x2+3!x3+4!x4+......+n!xn+....=ex
e
x
e^x
ex的泰勒展开式其实也很简单,因为他取的是0这个地方的导啊,并且
e
x
e^x
ex怎么导都是
e
x
e^x
ex。
暂时我只会n趋近于无限大的。。这个式子的意义自己思考一下?举几个栗子可能就明白了
l
n
(
1
+
x
)
=
x
−
x
2
2
+
x
3
3
−
x
4
4
+
x
5
5
−
.
.
.
.
.
.
.
.
ln(1+x)=x-\frac{x^2}{2}+\frac{x^3}{3}-\frac{x^4}{4}+\frac{x^5}{5}-........
ln(1+x)=x−2x2+3x3−4x4+5x5−........
容易推导
l
n
(
1
−
x
)
ln(1-x)
ln(1−x)的泰勒展开,就是把
x
x
x换为
−
x
-x
−x就可以了,然后你会发现,全部项都变成-的了。。
生成函数
每一个数列都会唯一对应一个生成函数,当然,生成函数也唯一对应一个序列
个人感觉这点虽然很显然但是也很重要
Coco_T_感觉写得挺好的
注意生成函数里面的x是没有任何意义的,你可以直接当做他收敛
NTT&FFT
这基本是多项式的基础
void NTT (LL *a,LL n,LL o)
{
for (LL u=0;u<n;u++) bin[u]=(bin[u>>1]>>1)|((u&1)*(n>>1));
for (LL u=0;u<n;u++) if (u<bin[u]) swap(a[u],a[bin[u]]);
for (LL u=1;u<n;u<<=1)
{
LL w,wn=Pow(o==1?GG:GGI,(MOD-1)/(u<<1)),t;
for (LL i=0;i<n;i=i+(u<<1))
{
w=1;
for (LL j=0;j<u;j++)
{
t=a[u+i+j]*w%MOD;
a[u+i+j]=(a[i+j]-t+MOD)%MOD;
a[i+j]=(a[i+j]+t)%MOD;
w=w*wn%MOD;
}
}
}
if (o==-1)
{
LL Inv=Pow(n,MOD-2);
for (LL u=0;u<n;u++) a[u]=a[u]*Inv%MOD;
}
}
多项式求逆
也是挺基础的一个东西。。
解法感觉十分自然简单
这里写得很好
学这个的时候,一定要理解好定义是什么
void get_inv (LL *a,LL *b,LL n)
{
if (n==1) {b[0]=Pow(a[0],MOD-2);return ;}
get_inv(a,b,n>>1);
LL nn=1;while (nn<=n) nn<<=1;
for (int u=0;u<n;u++) tmp[u]=a[u];
for (int u=n;u<nn;u++) b[u]=tmp[u]=0;
NTT(b,nn,1);NTT(tmp,nn,1);
for (int u=0;u<nn;u++) b[u]=((2-tmp[u]*b[u]%MOD)*b[u]%MOD+MOD)%MOD;
NTT(b,nn,-1);
for (int u=n;u<nn;u++) b[u]=0;
}
多项式ln
来自Mychael的博客
真是言简意赅
F
′
(
x
)
F'(x)
F′(x)就是直接求导就可以了,因为都是
a
∗
x
i
a*x^i
a∗xi的形式所以很好搞
然后就是一个多项式求逆
最后就是按求导的方法导回去就就可以了
void dao (LL *f,LL *a,LL n) {for (LL u=1;u<n;u++) a[u-1]=u*f[u]%MOD;a[n-1]=0;}
void jifen (LL *f,LL *a,LL n) {for (LL u=1;u<n;u++) a[u]=f[u-1]*Pow(u,MOD-2)%MOD;a[0]=0;}
void get_ln (LL *f,LL *g,LL n)
{
dao(f,A,n);get_inv(f,B,n);
LL nn=n<<1;
NTT(A,nn,1);NTT(B,nn,1);
for (LL u=0;u<nn;u++) A[u]=A[u]*B[u]%MOD;
NTT(A,nn,-1);jifen(A,g,n);
}
多项式Exp
来自租酥雨的公式
并不可以很好地理解这个公式。。先记下来吧。。
void get_EXP (LL *f,LL *g,LL n)
{
if (n==1) {g[0]=1;return ;}
get_EXP(f,g,n>>1);
for (LL u=0;u<n;u++) D[u]=g[u];
get_ln(g,E,n);
for (LL u=0;u<n;u++) C[u]=(f[u]+MOD-E[u])%MOD;C[0]++;
LL nn=(n<<1);
NTT(D,nn,1);NTT(C,nn,1);
for (LL u=0;u<nn;u++) D[u]=D[u]*C[u]%MOD;
NTT(D,nn,-1);
for (LL u=0;u<n;u++) g[u]=D[u];
for (LL u=n;u<nn;u++) E[u]=D[u]=0;
}