多項式全家桶(二):多項式的逆,導,積

       \ \ \ \ \ \ \,這一部分麻煩一點了,但是很重要,幾乎所有多項式都得用的,不過好在也不是很複雜的。


1. 多項式求逆

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

       \ \ \ \ \ \ \,求一個多項式 AA 的模 xnx^n 的逆元BB 時,假設先求出了模xn2x^{\frac{n}{2}} 的逆元 BB',既:

AB1 (mod xn2)A*B' \equiv 1\ (mod\ x^{\frac{n}{2}})

AB1 (mod xn)A*B \equiv 1\ (mod\ x^{n})

       \ \ \ \ \ \ \,那麼顯然存在:

AB1 (mod xn2)=ABA*B \equiv 1\ (mod\ x^{\frac{n}{2}})=A*B'

BB0 (mod xn2)B-B' \equiv 0\ (mod\ x^{\frac{n}{2}})

       \ \ \ \ \ \ \,兩邊同時平方:

B22BB+B20 (mod xn)B^2-2BB'+B'^2 \equiv 0\ (mod\ x^n)

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

(AB)B(AB)2B+AB2A0 (mod xn)(A*B)*B-(A*B)*2B'+A*B'^2 \equiv A*0\ (mod\ x^n)

B2B+AB20 (mod xn)B-2B'+A*B'^2 \equiv 0\ (mod\ x^n)

B2BAB2 (mod xn)B \equiv 2B'-A*B'^2\ (mod\ x^n)

       \ \ \ \ \ \ \,我們就可以倍增來處理它了,起點是B0A01(mod x1)B_0 \equiv A_0^{-1}(mod\ x^1)

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;\ \ \ \ \ \ \,按照公式來,公式挺簡單的,設多項式 AA 的導數爲 AA&#x27;

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

xA=AxA1x^{A&#x27;}=Ax^{A-1}

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

Ai=i×Ai+1A&#x27;_{i}=i\times A_{i+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;\ \ \ \ \ \ \,還是按照公式來,設多項式 AA 的積分爲 AA&#x27;

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

xAdx=1A+1xA1\int x^{A&#x27;}dx=\frac{1}{A+1}x^{A-1}

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

Ai=Ai1iA&#x27;_{i}=\frac{A_{i-1}}{i}

      &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;\ \ \ \ \ \ \,對於一個多項式FF,若是存在一個多項式GG,使得:

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

      &ThinSpace;\ \ \ \ \ \ \,那麼就稱多項式GG是多項式FF的複合逆。

      &ThinSpace;\ \ \ \ \ \ \,目前複合逆沒有O(nlogn)O(n \log n)的做法,但是可以用拉格朗日反演做到O(n2logn)O(n^2 \log n),既每一項每一項得求,求一項的時間是O(nlogn)O(n \log n)的,下面給出公式:

Gi=(xF)i1iiG_i=\frac{\left(\frac{x}{F}\right)^i_{i-1}}{i}

      &ThinSpace;\ \ \ \ \ \ \,那麼求逆和卷積就好了,xx都挺好處理的,證明很複雜,感興趣可以看這裏

      &ThinSpace;\ \ \ \ \ \ \,有一個值得注意的地方就是求逆的時候,應該直接求Fx\frac{F}{x}的逆,而不是FF的逆,因爲既然多項式 FF 存在複合逆,那麼常數項就應該是 00 ,這是不可能求逆的,先算出Fx\frac{F}{x}即可。

      &ThinSpace;\ \ \ \ \ \ \,若是需要O(nlogn)O(n \log n)只求一項,則需要用到快速冪,下一篇我們會講到

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章