多项式全家桶(二):多项式的逆,导,积

         \ \ \ \ \ \ \,       这一部分麻烦一点了,但是很重要,几乎所有多项式都得用的,不过好在也不是很复杂的。


1. 多项式求逆

         \ \ \ \ \ \ \,       P4238 【模板】多项式求逆

         \ \ \ \ \ \ \,       求一个多项式 A A A 的模 x n x^n xn 的逆元 B B B 时,假设先求出了模 x n 2 x^{\frac{n}{2}} x2n 的逆元 B ′ B' B,既:

A ∗ B ′ ≡ 1   ( m o d   x n 2 ) A*B' \equiv 1\ (mod\ x^{\frac{n}{2}}) AB1 (mod x2n)

A ∗ B ≡ 1   ( m o d   x n ) A*B \equiv 1\ (mod\ x^{n}) AB1 (mod xn)

         \ \ \ \ \ \ \,       那么显然存在:

A ∗ B ≡ 1   ( m o d   x n 2 ) = A ∗ B ′ A*B \equiv 1\ (mod\ x^{\frac{n}{2}})=A*B' AB1 (mod x2n)=AB

B − B ′ ≡ 0   ( m o d   x n 2 ) B-B' \equiv 0\ (mod\ x^{\frac{n}{2}}) BB0 (mod x2n)

         \ \ \ \ \ \ \,       两边同时平方:

B 2 − 2 B B ′ + B ′ 2 ≡ 0   ( m o d   x n ) B^2-2BB'+B'^2 \equiv 0\ (mod\ x^n) B22BB+B20 (mod xn)

         \ \ \ \ \ \ \,       再把 A A A 乘回去:

( A ∗ B ) ∗ B − ( A ∗ B ) ∗ 2 B ′ + A ∗ B ′ 2 ≡ A ∗ 0   ( m o d   x n ) (A*B)*B-(A*B)*2B'+A*B'^2 \equiv A*0\ (mod\ x^n) (AB)B(AB)2B+AB2A0 (mod xn)

B − 2 B ′ + A ∗ B ′ 2 ≡ 0   ( m o d   x n ) B-2B'+A*B'^2 \equiv 0\ (mod\ x^n) B2B+AB20 (mod xn)

B ≡ 2 B ′ − A ∗ B ′ 2   ( m o d   x n ) B \equiv 2B'-A*B'^2\ (mod\ x^n) B2BAB2 (mod xn)

         \ \ \ \ \ \ \,       我们就可以倍增来处理它了,起点是 B 0 ≡ A 0 − 1 ( m o d   x 1 ) B_0 \equiv A_0^{-1}(mod\ x^1) B0A01(mod x1)

inline Polynomial Inverse(const Polynomial &a){
	Polynomial ret,inv_a; 
	ret.resize(1);
  	ret[0]=Inv(a[0]);int ed=a.size();
	for(int len=2;len<=ed;len<<=1){
	 	int n=Prepare_Transformation(len+len);
	  	inv_a=a;inv_a.resize(n);ret.resize(n);
	  	for(int i=len;i<n;i++)inv_a[i]=0;
	  	NTT(inv_a,1);NTT(ret,1);
	  	for(int i=0;i<n;i++)ret[i]=1ll*(2ll-1ll*inv_a[i]*ret[i]%mod+mod)%mod*ret[i]%mod;
	  	NTT(ret,-1);
	  	//这里把比较复杂的卷积过程拖下来了。
	  	for(int i=len;i<n;i++)ret[i]=0;
	  	//这里不resize了,直接把多余的清零。
	}
	ret.resize(ed);
	//resize回来,防止以后长度爆炸。
	return ret;
}


2. 多项式求导

       &ThinSpace; \ \ \ \ \ \ \,       按照公式来,公式挺简单的,设多项式 A A A 的导数为 A ′ A&#x27; A

       &ThinSpace; \ \ \ \ \ \ \,       那么有:

x A ′ = A x A − 1 x^{A&#x27;}=Ax^{A-1} xA=AxA1

       &ThinSpace; \ \ \ \ \ \ \,       既:

A i ′ = i × A i + 1 A&#x27;_{i}=i\times A_{i+1} Ai=i×Ai+1

inline Polynomial Derivation(const Polynomial &a){
	int size=a.size();Polynomial ret;ret.resize(size);
  	for(int i=1;i<size;i++)ret[i-1]=1ll*i*a[i]%mod;
  	ret[size-1]=0;
	return ret;
}

3. 多项式求积

       &ThinSpace; \ \ \ \ \ \ \,       还是按照公式来,设多项式 A A A 的积分为 A ′ A&#x27; A

       &ThinSpace; \ \ \ \ \ \ \,       那么有:

∫ x A ′ d x = 1 A + 1 x A − 1 \int x^{A&#x27;}dx=\frac{1}{A+1}x^{A-1} xAdx=A+11xA1

       &ThinSpace; \ \ \ \ \ \ \,       既:

A i ′ = A i − 1 i A&#x27;_{i}=\frac{A_{i-1}}{i} Ai=iAi1

       &ThinSpace; \ \ \ \ \ \ \,       那就是乘逆元咯 (兄弟俩长得挺像

inline Polynomial Integral(const Polynomial &a){
	int size=a.size();Polynomial ret;ret.resize(size);
  	for(int i=1;i<size;i++)ret[i]=1ll*Inv(i)*a[i-1]%mod;
  	ret[0]=0;
	return ret;
}

4. 多项式复合逆

       &ThinSpace; \ \ \ \ \ \ \,       NFLSOJ #332. 多项式复合逆

       &ThinSpace; \ \ \ \ \ \ \,       对于一个多项式 F F F,若是存在一个多项式 G G G,使得:

G ( F ( x ) ) = x G(F(x))=x G(F(x))=x

       &ThinSpace; \ \ \ \ \ \ \,       那么就称多项式 G G G是多项式 F F F的复合逆。

       &ThinSpace; \ \ \ \ \ \ \,       目前复合逆没有 O ( n log ⁡ n ) O(n \log n) O(nlogn)的做法,但是可以用拉格朗日反演做到 O ( n 2 log ⁡ n ) O(n^2 \log n) O(n2logn),既每一项每一项得求,求一项的时间是 O ( n log ⁡ n ) O(n \log n) O(nlogn)的,下面给出公式:

G i = ( x F ) i − 1 i i G_i=\frac{\left(\frac{x}{F}\right)^i_{i-1}}{i} Gi=i(Fx)i1i

       &ThinSpace; \ \ \ \ \ \ \,       那么求逆和卷积就好了, x x x都挺好处理的,证明很复杂,感兴趣可以看这里

       &ThinSpace; \ \ \ \ \ \ \,       有一个值得注意的地方就是求逆的时候,应该直接求 F x \frac{F}{x} xF的逆,而不是 F F F的逆,因为既然多项式 F F F 存在复合逆,那么常数项就应该是 0 0 0 ,这是不可能求逆的,先算出 F x \frac{F}{x} xF即可。

       &ThinSpace; \ \ \ \ \ \ \,       若是需要 O ( n log ⁡ n ) O(n \log n) O(nlogn)只求一项,则需要用到快速幂,下一篇我们会讲到

inline Polynomial Composition_Inverse(const Polynomial &a){
	int n=a.size();
  	Polynomial ret,Cinv=a,Pow;
  	Cinv.resize(n);ret.resize(n);Pow.resize(n);Pow[0]=1;
  	for(register int i=0;i<n-1;i++)Cinv[i]=Cinv[i+1];Cinv[n-1]=0;
  	Cinv=Inverse(Cinv);
  	for(register int i=1;i<n;++i){
  		Pow=Pow*Cinv;Pow.resize(n);
  		ret[i]=1ll*Pow[i-1]*Inv(i)%mod;
	}
  	return ret;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值