生成函数&多项式学习笔记

生成函数

泰勒多项式

对于函数ff,设他在点x0x_0处存在直到nn阶的导数,构造一个nn次多项式:

Tn(x)=f(x0)+f(x0)1!(xx0)+f(x0)2!(xx0)2+...+f(n)(x0)n!(xx0)nTn(x)=i=0i=nf(i)(x0)i!(xx0)iT_n(x)=f(x_0)+\frac{f'(x_0)}{1!}(x-x_0)+\frac{f''(x_0)}{2!}(x-x_0)^2+...+\frac{f^{(n)}(x_0)}{n!}(x-x_0)^n\\T_n(x)=\sum_{i=0}^{i=n}\frac{f^{(i)}(x_0)}{i!}(x-x_0)^i

x0=0x_0=0时有麦克劳林公式

泰勒展开

函数ff的泰勒多项式即为其泰勒展开

重要函数泰勒展开:

ex=i=0xii!ln(1+x)=i=1(1)i+1xii11+x=i=0(1)ixi11x=i=0xi11qx=i=0qixi(1+x)a=i=0j=1n(aj+1)i!xie^x=\sum_{i=0}^{\infty}\frac{x^i}{i!}\\ ln(1+x)=\sum_{i=1}^{\infty}(-1)^{i+1}\frac{x^i}{i}\\ \frac{1}{1+x}=\sum_{i=0}^{\infty}(-1)^ix^i\\ \frac{1}{1-x}=\sum_{i=0}^{\infty}x^i\\ \frac{1}{1-qx}=\sum_{i=0}^{\infty}q^ix^i\\ (1+x)^a=\sum_{i=0}^{\infty}\frac{\prod_{j=1}^n(a-j+1)}{i!}x^i

普通生成函数

对于一个无穷序列aa,定义其普通生成函数为i=0aixi\sum_{i=0}^{\infty}a_ix^i

小练习:

  1. 序列1,0,1,0...{1,0,1,0...}的普通生成函数为i=0x2i=i=0(x2)i=11x2\sum_{i=0}^{\infty}x^{2i}=\sum_{i=0}^{\infty}(x^2)^{i}=\frac{1}{1-x^2}

  2. 序列0,1,0,1...{0,1,0,1...}的普通生成函数为xi=0x2i=xi=0(x2)i=x1x2x\sum_{i=0}^{\infty}x^{2i}=x\sum_{i=0}^{\infty}(x^2)^{i}=\frac{x}{1-x^2}

序列右移普通生成函数乘以xx,记得处理好常数项

  1. 序列1,2,3,...n,...1,2,3,...n,...的普通生成函数为i=0(i+1)xi=i=1ixi1=i=1(xi)=(i=0xi1)=(11x1)=1(1x)2\sum_{i=0}^{\infty}(i+1)x^i=\sum_{i=1}^{\infty}ix^{i-1}=\sum_{i=1}^{\infty}(x^i)'=(\sum_{i=0}^{\infty}x^i-1)'=(\frac 1 {1-x}-1)'=\frac{1}{(1-x)^2}

    是不是怪复杂的,其实我们可以使用错位相减的思路

    SS为该序列普通生成函数

    S=1+2x+3x2+4x3+...xS=0+x+2x2+3x3+...(1x)S=1+x+x2+x3+...=11xS=1(1x)2S=1+2x+3x^2+4x^3+...\\xS=0+x+2x^2+3x^3+...\\(1-x)S=1+x+x^2+x^3+...=\frac{1}{1-x}\\S=\frac{1}{(1-x)^2}

  2. 序列1,3,5,7,...,2n1,...1,3,5,7,...,2n-1,...的普通生成函数为SS

    S=1+3x+5x2+7x3+...xS=0+x+3x2+5x3+...(1x)S=1+2x+2x2+2x3+...=1+2x1x=1+x(1x)2S=1+3x+5x^2+7x^3+...\\xS=0+x+3x^2+5x^3+...\\(1-x)S=1+2x+2x^2+2x^3+...=1+\frac{2x}{1-x}=\frac{1+x}{(1-x)^2}

Fibonacci\text{Fibonacci}的普通生成函数:

S=11xx2S=\frac1 {1-x-x^2}

CatlanCatlan的普通生成函数:

G=i=0cixi=i=0ci+1xi+1+1=i=0j=0icjcijxi+1+1=xi=0j=0icjxjcijxij+1=xj=0cjxji=jcijxij+1G=\sum_{i=0}^{\infty}c_ix^i=\sum_{i=0}^{\infty}c_{i+1}x^{i+1}+1\\=\sum_{i=0}^{\infty}\sum_{j=0}^{i}c_jc_{i-j} x^{i+1}+1=x\sum_{i=0}^{\infty}\sum_{j=0}^{i}c_jx^jc_{i-j}x^{i-j}+1\\=x\sum_{j=0}^{\infty}c_jx^j\sum_{i=j}^{\infty}c_{i-j}x^{i-j}+1

k=ijk=i-j

G=xj=0cjxjk=0ckxk+1=xG2+1G=x\sum_{j=0}^{\infty}c_jx^j\sum_{k=0}^{\infty}c_kx^k+1=xG^2+1

G=1±14x2xG=\frac{1\pm \sqrt{1-4x}}{2x}

观察GG的常数项,由于xx非变量

考虑将1x1-x泰勒展开

1x=1+x2x28+...14x=12x2x2+...\sqrt{1-x}=1+\frac x 2-\frac {x^2} 8+...\\\sqrt{1-4x}=1-2x-2x^2+...

若取加号

G=22x2x22x=1x1xG=\frac{2-2x-2x^2}{2x}=\frac 1 x-1-x

常数项不对

取减号符合

G=114x2xG=\frac{1-\sqrt{1-4x}}{2x}

GG泰勒展开整理一波可以得到cnc_n的通项

cn=1k+1C2kkc_n=\frac 1 {k+1}C_{2k}^k

指数生成函数

对于一个无穷序列aa,定义其普通生成函数为i=0aixii!\sum_{i=0}^{\infty}a_i\frac{x^i}{i!}

普通生成函数通常用来解决无标号计数问题,指数生成函数通常用来解决带标号的计数问题。

排列数P,pn=n!\text{P},p_n=n!的指数生成函数:11x\frac 1 {1-x}

圆排列数Ccn=(n1)!\text{C},c_n=(n-1)!的指数生成函数:ln(11x)ln(\frac{1}{1-x})

注意到P=eCP=e^C,这是一个非常有趣的性质

考虑排列数和圆排列数的关系

将排列做一个置换群分解

每一个排列唯一对应一个置换群集合

对于确定的nn个位置组成的置换,其方案数有(n1)!=cn(n-1)!=c_n即圆排列

故每一个排列能拆成若干个圆排列

可以证明像P\text P这样能分解成若干个C\text C指数生成函数

P=eCP=e^C

eg:

nn个点形成森林的方案数的指数生成函数为F\text F

nn个点形成树的方案数的指数生成函数为T\text T

F=eTF=e^T

错排数的指数生成函数F\text F可以分解成若干个无自环的置换D\text D

D=CxF=eDD=C-x\\F=e^D

nn个点的有标号无向连通图个数的指数生成函数为F\text F

nn个点的有标号无向图个数的指数生成函数为G\text G

G=eFG=e^F

多项式

多项式的表示

小学我们就学过多项式的概念

例如F(x)=x2+2x+1F(x)=x^2+2x+1这就是一个二次多项式

多项式的系数表示法

这是一般的多项式常用的表示方法

对于一个nn次多项式,我们可以用n+1n+1个系数表示出这个多项式

例如上面的F(x)F(x),我们可以用1,2,11,2,1表示这个多项式

多项式的点值表示法

我们可以把一个多项式理解成一个高次函数

对于每一个xx我们都能得到这个函数的一个yy值(点值)

对于一个nn次多项式,我们可以用n+1n+1个点值表示出这个多项式

例如上面的F(x)F(x),我们可以用1,4,91,4,9来表示出这个多项式

多项式加法

F(x)+G(x)F(x)+G(x),F(x)F(x)nn次多项式,G(x)G(x)mm次多项式,不妨设n<mn<m

对于系数表示法,把两个多项式的系数相加即可

对于点值表示法,取mm个不同的xx值代入两个多项式得到的点值相加即可

多项式乘法

F(x)×G(x)F(x)\times G(x),F(x)F(x)nn次多项式,G(x)G(x)mm次多项式,不妨设n<mn<m

我们可以将多项式乘法理解为数字竖式乘法的形式

对于系数表示法,O(nm)O(nm)枚举即可

对于点值表示法,取n+mn+m个不同的xx值代入两个多项式中得到的点值相乘即可

多项式乘法

FFT

快速傅里叶变换Fast Fast TLE

复数

了解这部分可以跳过

初一时我们学过实数的概念

我们也学过一元二次方程

当碰到x2+2x+2=0x^2+2x+2=0这样Δ<0\Delta<0的方程时

老师告诉我们这是无实数解的,因为负数在实数范围内没有平方根

但在复数范围内一切皆有可能

复数域也是目前最大的定义域

定义与复平面

我们把形如z=a+biz=a+bia,ba,b均为实数)的数称为复数,其中aa称为实部,bb称为虚部,ii称为虚数单位。当zz的虚部等于零时,常称zz为实数;当zz虚部不等于零时,实部等于零时,常称zz纯虚数

——摘自百度百科

我们可以把复数域映射到平面直角坐标系上,一般称该平面为复平面

用一个点(a,b)(a,b)表示一个复数,对应a+bia+bi

复数的三角形式

一个复数可以表示成z=r(cosθ+isinθ)z=r(cos\theta+isin\theta)的形式,rrzz的模,θ\thetazz的辐角

复数的运算

z1=a1+b1i=r1(cosθ1+isinθ1),z2=a2+b2i=r2(cosθ2+isinθ2)z_1=a_1+b_1i=r_1(cos\theta_1+isin\theta_1),z_2=a_2+b_2i=r_2(cos\theta_2+isin\theta_2)

z1+z2=(a1+a2)+(b1+b2)iz1z2=(a1a2b1b2)+(a1b2+a2b1)iz1z2=r1r2(cos(θ1+θ2)+isin(θ1+θ2))z1z2=r1r2(cos(θ1θ2)+isin(θ1θ2))z_1+z_2=(a_1+a_2)+(b_1+b_2)i\\z_1*z_2=(a_1*a_2-b_1*b_2)+(a_1*b_2+a_2*b_1)i\\z_1*z_2=r_1*r_2(cos(\theta_1+\theta_2)+isin(\theta_1+\theta_2))\\\frac{z_1}{z_2}=\frac{r_1}{r_2}(cos(\theta_1-\theta_2)+isin(\theta_1-\theta_2))

具体推算过程可以去系统的学习一下复数,毕竟我们在搞OI

单位根

我们称方程xn=1x^n=1的所有复数解ωnk,k[0,n1]\omega_n^k,k\in[0,n-1]nn次单位根

ωnk=cos2kπn+isin2kπn\omega_n^k=cos\frac{2k\pi}{n}+isin\frac{2k\pi}{n}

显然ωn0=1\omega_n^0=1

性质

1.(ωn1)k=ωnk(\omega_n^1)^k=\omega_n^k

由定义易知

2.ωnk=ω2n2k\omega_n^k=\omega_{2n}^{2k}

ω2n2k=cos4kπ2n+isin4kπ2n=cos2kπn+isin2kπn=ωnk\omega_{2n}^{2k}=cos\frac{4k\pi}{2n}+isin\frac{4k\pi}{2n}=cos\frac{2k\pi}{n}+isin\frac{2k\pi}{n}=\omega_n^k

3.ωnk=ωnk+n2,k<n2\omega_n^k=-\omega_n^{k+\frac n 2},k<\frac n 2

ωnk+n2=ωnkωnn2=ωnk(cosπ+isinπ)=ωnk\omega_n^{k+\frac n 2}=\omega_n^k*\omega_n^{\frac n 2}=\omega_n^k*(cos\pi+isin\pi)=-\omega_n^k

FFT推导

问题叙述:

给定一个 nn 次多项式 F(x)F(x),和一个 mm 次多项式 G(x)G(x),求出 F(x)F(x)G(x)G(x) 的卷积(F(x)×G(x)F(x)\times G(x)的每项系数)

F(x)=a0+a1x+a2x2+...+anxnG(x)=b0+b1x+b2x2+...+bnxmF(x)=a_0+a_1x+a_2x^2+...+a_nx^n\\G(x)=b_0+b_1x+b_2x^2+...+b_nx^m


先将F(x)F(x)由系数表示法变成点值表示法,由于暴力是O(n×(n+m))O(n\times(n+m))的,我们需要更优秀的做法

默认nn22的次幂

F(x)F(x)xx幂次的奇偶性分离

F0(x)=a0+a2x+a4x2+anxn2F1(x)=a1+a3x+a5x2+an1xn21F_0(x)=a_0+a_2x+a_4x^2+a_nx^{\frac n 2}\\F_1(x)=a_1+a_3x+a_5x^2+a_{n-1}x^{\frac n 2-1}

F(x)=F0(x2)+xF1(x2)F(x)=F_0(x^2)+xF_1(x^2)

代入x=ωnk,x=ωnk+n2,k<n2x=\omega_n^k,x=\omega_n^{k+\frac n 2},k<\frac n 2

F(ωnk)=F0(ωn2k)+ωnkF1(ωn2k)F(\omega_n^k)=F_0(\omega_n^{2k})+\omega_n^kF_1(\omega_n^{2k})

F(ωnk+n2)=F0(ωn2k+n)+ωnk+n2F1(ωn2k+n)F(\omega_n^{k+\frac n 2})=F_0(\omega_n^{2k+n})+\omega_n^{k+\frac n 2}F_1(\omega_n^{2k+n})

ωnn=1\omega_n^n=1

F(ωnk+n2)=F0(ωn2k)+ωnk+n2F1(ωn2k)F(\omega_n^{k+\frac n 2})=F_0(\omega_n^{2k})+\omega_n^{k+\frac n 2}F_1(\omega_n^{2k})

ωnk=ωnk+n2\omega_n^k=-\omega_n^{k+\frac n 2}

F(ωnk+n2)=F0(ωn2k)ωnkF1(ωn2k)F(\omega_n^{k+\frac n 2})=F_0(\omega_n^{2k})-\omega_n^kF_1(\omega_n^{2k})

我们惊喜的发现F(ωnk)F(\omega_n^k)F(ωnk+n2)F(\omega_n^{k+\frac n 2})的求式不同点只有F1(x)F_1(x)这一项的系数互为相反数

而对于F0(x),F1(x)F_0(x),F_1(x)这两个多项式都可以重复上述过程继续奇偶分离做

这也是我们需要nn为2的次幂的原因

void FFT(C *a,int lim,int opt){
	if(lim==1)return ;
	C a1[(lim>>1)+5],a2[(lim>>1)+5];
	for(int i=0;i<=lim;i+=2){
		a1[i>>1]=a[i];//F_0
		a2[i>>1]=a[i+1];//F_1
	}
	FFT(lim>>1,a1,opt);
	FFT(lim>>1,a2,opt);
	C w=(C){cos(2.0*pai/lim),opt*sin(2.0*pai/lim)};//lim次单位根
	C p=(C){1,0};
	for(int i=0;i<(lim>>1);i++,p=p*w){
		C t=p*a2[i];
		a[i]=a1[i]+t;
		a[i+(lim>>1)]=a1[i]-t;
	}
	return ;
}

我们能发现FFT\text{FFT}合并的顺序为原顺序的二进制反转,得出非递归版,这个部分不过多叙述

void FFT(C *a,int lim,int opt){
	for(int i=0;i<lim;i++)if(i<r[i])swap(a[i],a[r[i]]);
	for(int mid=1;mid<lim;mid<<=1){//枚举中点
		C w=(C){cos(pai/mid),opt*sin(pai/mid)};
		int len=mid<<1;//长度
		for(int j=0;j<lim;j+=len){//每段起始位置
			C p=(C){1,0};
			for(int k=0;k<mid;k++,p=p*w){//每段前半段
				C u=a[j+k],v=p*a[j+mid+k];
				a[j+k]=u+v;
				a[j+mid+k]=u-v;
			}
		}
	}
	return ;
}

NTT

快速数论变换

由于复数运算常数巨大,且有精度问题,在模意义下,NTT\text{NTT}利用原根完成和FTT\text{FTT}完全相同的操作

void NTT(long long *f,int lim,int opt){
	for(int i=0;i<lim;i++)if(i<r[i])swap(f[i],f[r[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		long long wn=power(opt==1?G:Gi,(mod-1)/(mid<<1));
		int len=mid<<1;
		for(int j=0;j<lim;j+=len){
			long long w=1;
			for(int k=0;k<mid;k++,w=w*wn%mod){
				long long u=f[j+k],v=w*f[j+k+mid]%mod;
				f[j+k]=(u+v)%mod;
				f[j+k+mid]=(u-v+mod)%mod;
			}
		}
	}
	if(opt==1)return ;
	long long inv=power(lim,mod-2);
	for(int i=0;i<lim;i++)f[i]=f[i]*inv%mod;
	return ;
}

这里放一份速度还行的预处理原根板子

int pw[2][4*maxn];
void pre(int lim){
	int c=0;
	for(int i=1;i<lim;i<<=1,c++){
		pw[0][i]=pw[1][i]=1;
		pw[0][i+1]=power(G,(mod-1)/(i<<1));
		pw[1][i+1]=power(Gi,(mod-1)/(i<<1));
		for(int j=2;j<i;j++){
			pw[0][i+j]=1ll*pw[0][i+j-1]*pw[0][i+1]%mod;
			pw[1][i+j]=1ll*pw[1][i+j-1]*pw[1][i+1]%mod;
		}
	}
	return ;
}
void NTT(int *f,int lim,int opt){
	for(int i=1;i<lim;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
	int op=(opt==-1),c=0;
	for(int mid=1;mid<lim;mid<<=1,c++){
		for(int j=0;j<lim;j+=(mid<<1)){
			for(int k=0;k<mid;k++){
				int u=f[j+k],v=1ll*f[j+k+mid]*pw[op][mid+k]%mod;
				f[j+k]=add(u+v);
				f[j+k+mid]=sub(u-v);
			}
		}
	}
	if(opt==1)return;
	int inv=power(lim,mod-2);
	for(int i=0;i<lim;i++)f[i]=1ll*f[i]*inv%mod;
	return ;
}

任意模数多项式乘法

一种是三模NTT(做9次ntt),另一种是MTT(7次FFT或4次FFT)

MTT(拆系数FFT)

指毛爷爷在2016年国家集训队论文中给出的优秀任意模数多项式乘法优化

我们把两 n[1,105]n\in[1,10^5] 次多项式系数值域定为 [1,109][1,10^9] ,模数为 [1,109][1,10^9] 的一个质数 pp

那么答案是 102310^{23} 级别,double精度不够

考虑一个 bw,wb\sim \sqrt w,w为值域 把系数分成两部分计算

F(x)=bA(x)+B(x)G(x)=bC(x)+D(x)F(x)=bA(x)+B(x)\\G(x)=bC(x)+D(x)

F(x)G(x)=b2A(x)C(x)+b(A(x)D(x)+B(x)C(x))+B(x)D(x)F(x)G(x)=b^2A(x)C(x)+b(A(x)D(x)+B(x)C(x))+B(x)D(x)

三个部分的多项式乘法值域为 [1,1015][1,10^{15}] ,double的精度足够处理

至此,我们得到了一个7次FFT的做法(对 A,B,C,DA,B,C,D 分别dft一次,对 AC,AD+BC,BDAC,AD+BC,BD 分别idft3次)

接下来考虑将两个多项式的点值表示由一遍dft得到

P(x)=A(x)+iB(x)Q(x)=A(x)iB(x)P(x)=A(x)+iB(x)\\Q(x)=A(x)-iB(x)

若得到了 P,QP,Q 两辅助多项式,我们通过加减即能得到 A,BA,B

考虑 P,QP,Q 的关系

P(ωk)=A(ωk)+iB(ωk)=j=0najωjk+ibjωjk=j=0n(aj+ibj)(cos2πjkn+isin2πjkn)P(\omega^k)=A(\omega^k)+iB(\omega^k)=\sum_{j=0}^na_j\omega^{jk}+ib_j\omega^{jk}\\=\sum_{j=0}^n(a_j+ib_j)(\cos\frac{2\pi jk}{n}+i\sin \frac{2\pi jk}{n})

X=cos2πjkn+isin2πjknX=\cos\frac{2\pi jk}{n}+i\sin \frac{2\pi jk}{n}

P(ωk)=j=0n(aj+ibj)(cosX+isinX)=j=0najcosX+iajsinX+ibjcosXbjsinX=j=0najcosXbjsinX+i(ajsinX+bjcosX)P(\omega^k)=\sum_{j=0}^n(a_j+ib_j)(\cos X+i\sin X)=\sum_{j=0}^na_j\cos X+ia_j\sin X+ib_j\cos X-b_j\sin X\\=\sum_{j=0}^na_j\cos X-b_j\sin X+i(a_j\sin X+b_j\cos X)

Q(ωk)=j=0n(ajibj)(cosX+isinX)=j=0najcosX+iajsinXibjcosX+bjsinX=j=0najcosX+bjsinX+i(ajsinXbjcosX)Q(\omega^k)=\sum_{j=0}^n(a_j-ib_j)(\cos X+i\sin X)=\sum_{j=0}^na_j\cos X+ia_j\sin X-ib_j\cos X+b_j\sin X\\=\sum_{j=0}^na_j\cos X+b_j\sin X+i(a_j\sin X-b_j\cos X)

conj(x)\text{conj}(x) 表示 xx 的共轭复数

Q(ωnk)=j=0najcosXbjsinXi(ajsinX+bjcosX)=conj(P(ωk))Q(\omega^{n-k})=\sum_{j=0}^na_j\cos X-b_j\sin X-i(a_j\sin X+b_j\cos X)=\text{conj}(P(\omega^k))

那么我们对 PP dft一次就能得到 P,QP,Q 的点值表达了!

我们成功的得到了一个一次dft,一次idft求卷积的神必做法

同时,我们也得到了两次dft,两次idft求任意模数多项式乘法的神必做法!

多项式求导与不定积分

void dervt(int lim,long long *f){
	for(int i=0;i<lim-1;i++)f[i]=f[i+1]*(i+1)%mod;
	f[lim-1]=0;
	return ;
}
void integ(int lim,long long *f){
	for(int i=lim-1;i>=1;i--)f[i]=f[i-1]*power(i,mod-2)%mod;
	f[0]=0;
	return ;
}

多项式求逆

【模板】多项式乘法逆

即给定n1n-1次多项式F(x)\text{F(x)},求多项式G(x)\text{G(x)}满足,F(x)G(x)1modxn\text{F(x)}*\text{G(x)}\equiv1\mod x^n

考虑递归求解

已知

HFH1modxn2FG1modxn\text H\\\text{F}*\text{H}\equiv1\mod x^{\frac n 2}\\\text{F}*\text{G}\equiv1\mod x^n

GH0modxn2(GH)20modxnG22GH+H20modxnG2H+FH20modxnG2HFH2modxn\text{G}-\text{H}\equiv0\mod x^{\frac n 2}\\(\text{G}-\text{H})^2\equiv0\mod x^n\\\text{G}^2-2\text{GH}+\text{H}^2\equiv 0 \mod x^n\\\text{G}-2\text{H}+\text{FH}^2\equiv0\mod x^n\\\text G\equiv2\text H-\text {FH}^2\mod x^n

时间复杂度T(n)=T(n2)+O(nlogn)=O(nlogn)T(n)=T(\frac n 2)+O(nlogn)=O(nlogn)

long long A[maxn<<2];
void inv(int n,long long *f,long long *g){
	if(n==1){g[0]=power(f[0],mod-2);return ;}
	inv((n+1)>>1,f,g);
	int lim=1,k=0;
	while(lim<(n<<1))lim<<=1,k++;
	for(int i=1;i<lim;i++)r[i]=r[i>>1]>>1|((i&1)<<k-1);
	for(int i=0;i<n;i++)A[i]=f[i];
	for(int i=n;i<lim;i++)g[i]=A[i]=0;
	NTT(g,lim,1);NTT(A,lim,1);
	for(int i=0;i<lim;i++)g[i]=(2ll*g[i]%mod-A[i]*g[i]%mod*g[i]%mod+mod)%mod;
	NTT(g,lim,-1);
	for(int i=n;i<lim;i++)g[i]=0;
	return ;
}

多项式开根

【模板】多项式开根

即给定n1n-1次多项式F(x)\text{F(x)},求多项式G(x)\text{G(x)}满足,G(x)2F(x)modxn\text{G(x)}^2\equiv \text{F(x)}\mod x^n

同样递归求解

已知

HH2Fmodxn2G2Fmodxn\text H\\\text H^2\equiv \text F\mod x^{\frac n 2}\\\text G^2\equiv \text F\mod x^n

GHmodxn2GH0modxn2G22GH+H20modxnGF+H22H\text G\equiv \text H\mod x^{\frac n 2}\\\text G-\text H\equiv0\mod x^{\frac n 2}\\\text G^2-2\text{GH}+\text H^2\equiv 0 \mod x^n\\\text G\equiv\frac{\text F+\text H^2}{2\text H}

求逆即可

long long B[maxn<<2],C[maxn<<2];
long long inv2=power(2,mod-2);
void sqrt(int n,long long *f,long long *g){
	if(n==1){g[0]=1;return ;}
	sqrt((n+1)>>1,f,g);
	inv(n,g,B);
	int lim=1,k=0;
	while(lim<(n<<1))lim<<=1,k++;
	for(int i=1;i<lim;i++)r[i]=r[i>>1]>>1|((i&1)<<k-1);
	for(int i=0;i<n;i++)C[i]=f[i];
	for(int i=n;i<lim;i++)B[i]=C[i]=0;
	NTT(g,lim,1);NTT(B,lim,1);NTT(C,lim,1);
	for(int i=0;i<lim;i++)g[i]=(C[i]+g[i]*g[i]%mod)%mod*inv2%mod*B[i]%mod;
	NTT(g,lim,-1);
	for(int i=n;i<lim;i++)g[i]=0;
	return ;
}

多项式ln\text{ln}

【模板】多项式对数函数(多项式 ln)

即给定n1n-1次多项式F(x)\text{F(x)},求多项式G(x)\text{G(x)}满足,G(x)ln F(x)modxn\text{G(x)}\equiv \text{ln F(x)}\mod x^n

与前两种思路不太一样,对两边求导

GFFmodxn\text G'\equiv\frac {\text F'}{\text F}\mod x^n

求逆+求导+不定积分即可

long long D[maxn<<2];
void ln(int n,long long *f,long long *g){
	for(int i=0;i<n;i++)D[i]=f[i];
	inv(n,D,g);
	dervt(n,D);
	int lim=1,k=0;
	while(lim<(n<<1))lim<<=1,k++;
	for(int i=1;i<lim;i++)r[i]=((r[i>>1]>>1)|((i&1)<<(k-1)));
	NTT(D,lim,1);NTT(g,lim,1);
	for(int i=0;i<lim;i++)g[i]=D[i]*g[i]%mod;
	NTT(g,lim,-1);
	integ(n,g);
	for(int i=n;i<lim;i++)g[i]=0;
	for(int i=0;i<lim;i++)D[i]=0; 
	return ;
}

牛顿迭代

即给定n1n-1次多项式F(x)\text{F(x)},求多项式G(x)\text{G(x)}满足,F(G(x))0modxn\text{F(G(x))}\equiv 0\mod x^n

同样递归求解

已知

H(x)F(H(x))0modxn2\text{H(x)}\\\text{F(H(x))}\equiv 0\mod x^{\frac n 2}

F(G(x))\text{F(G(x))}H(x)\text{H(x)}处泰勒展开

F(G(x))=i=0i=nF(i)(H(x))i!(G(x)H(x))i0modxnF(G(x))=\sum_{i=0}^{i=n}\frac{F^{(i)}(H(x))}{i!}(G(x)-H(x))^i\equiv 0 \mod x^n

由于 G(x)H(x)G(x)-H(x) 的最低非0系数项为 xn2x^{\frac n 2}

则对于任意 i2,(G(x)H(x))i0modxni\geq 2,(G(x)-H(x))^i\equiv 0\mod x^n

F(G(x))H(x)F(H(x))F(H(x))modxnF(G(x))\equiv H(x)-\frac{F(H(x))}{F'(H(x))} \mod x^n

多项式exp\text{exp}

【模板】多项式指数函数(多项式 exp)

即给定n1n-1次多项式F(x)\text{F(x)},求多项式G(x)\text{G(x)}满足,G(x)eF(x)modxn\text{G(x)}\equiv e^\text{F(x)}\mod x^n

两边同时取ln\text{ln}

ln GFmodxn\text{ln G}\equiv \text F \mod x^n

定义H(x)=ln x-F\text{H(x)}=\text{ln x-F},则

H(G)0modxn\text{H(G)}\equiv 0\mod x^n

牛顿迭代

long long E[maxn<<2],F[maxn<<2];
void exp(int n,long long *f,long long *g){
	if(n==1){g[0]=1;return ;}
	exp((n+1)>>1,f,g);
	ln(n,g,E);
	int lim=1,k=0;
	while(lim<=(n<<1))lim<<=1,k++;
	for(int i=1;i<lim;i++)r[i]=((r[i>>1]>>1)|((i&1)<<(k-1)));
	for(int i=0;i<n;i++)F[i]=f[i];
	for(int i=n;i<lim;i++)E[i]=F[i]=0;
	for(int i=0;i<lim;i++)F[i]=((F[i]-E[i])%mod+mod)%mod;
	F[0]++;
	NTT(g,lim,1);NTT(F,lim,1);
	for(int i=0;i<lim;i++)g[i]=g[i]*F[i]%mod;
	NTT(g,lim,-1);
	for(int i=n;i<lim;i++)g[i]=0;
	for(int i=0;i<n;i++)E[i]=0;
	return ;
}

多项式快速幂

【模板】多项式快速幂

long long H[maxn<<2];
void power(int n,int k,long long *f,long long *g){
	ln(n,f,g);
	for(int i=0;i<n;i++)g[i]=g[i]*k%mod;
	exp(n,g,H);
	for(int i=0;i<n;i++)g[i]=H[i];
	return ;
}

多项式除法

多项式多点求值

多项式多点插值

多项式复合逆