多項式全家桶(三):多項式的ln,exp

       \ \ \ \ \ \ \,對數和指數是很重要的東西了,複雜的多項式都和他們有關係,所以說掌握很重要,這裏不建議光背板子,因爲這兩個板子都有致命的限制,而在實際操作的時候,可以通過一些方法繞過這個限制直接求解,這個就很重要了。


1. 多項式的lnln

       \ \ \ \ \ \ \,P4725 【模板】多項式對數函數

       \ \ \ \ \ \ \,公式先走起咯:

ln(A)=AAdx\ln(A)=\int \frac{A'}{A}dx

       \ \ \ \ \ \ \,觀察公式,一句話解決:

       \ \ \ \ \ \ \,導卷逆的積:

       \ \ \ \ \ \ \,看上去很模板,當然模板也是很短的:

inline Polynomial Logarithmic(const Polynomial &a){
	Polynomial ln_a=Derivation(a)*Inverse(a);
  	ln_a.resize(a.size());
  	//這裏resize一下,因爲卷積後會倍增,防止變長爆掉
  	return Integral(ln_a);
}

       \ \ \ \ \ \ \,還有一個值得注意的問題,一般求對數的多項式,是需要要求常數項爲 11 的,因爲我們知道:

e0=1e^0=1

       \ \ \ \ \ \ \,也就是:

ln(1)=0ln(1)=0

       \ \ \ \ \ \ \,這樣算出來的 lnln 常數項是 00,而我們追後一步在算積的時候,是默認把常數項補上 00 的,這樣就沒有問題。可要是原多項式常數項不爲 11 呢?

       \ \ \ \ \ \ \,顯然應該算積的時候在常數項補上 ln(C)ln(C) (C爲常數項),不過這個數在模的意義下應該是多少呢?這個問題周道確實不能解決了,所以說,模板題的話,會給出這個常數項爲 11的條件的。

       \ \ \ \ \ \ \,否認常數項不等於11,完全不能求 lnln 的說法。


2. 多項式的expexp

P4726 【模板】多項式指數函數

       \ \ \ \ \ \ \,這玩意說簡單也簡單,說複雜也挺複雜的,我們得引入一個新玩意,【牛頓迭代】,是求函數零點的玩意,收斂速度非常理想,我在這裏有簡略的講過:【導數和牛頓迭代】,我也在洛谷出過一個牛頓迭代的裸題,感興趣可以去體驗一下牛頓迭代的神奇:【P4986 逃離】

       \ \ \ \ \ \ \,說遠了,現在我們來康康怎麼求指數函數。

       \ \ \ \ \ \ \,令我們要求的是 AA 的指數函數 BB,既是:

B=eAB=e^A

       \ \ \ \ \ \ \,變形得:

ln(B)A=0\ln(B)-A=0

       \ \ \ \ \ \ \,咦?00 ?,我們把多項式當做函數值看看?

       \ \ \ \ \ \ \,哇,函數零點!馬上牛頓迭代呀!

       \ \ \ \ \ \ \,F(B)=ln(B)AF(B)=\ln (B)-A,我們要求 FF的零點,根據牛頓迭代的公式可得(注意這裏B後面的括號的迭代版本的意思,不是多項式的項):

B(x)=B(x1)F(B(x1))F(B(x1))B(x)=B(x-1)-\frac{F\left(B(x-1)\right)}{F'\left(B(x-1)\right)}

       \ \ \ \ \ \ \,而根據導數的定義,F(B)=1BF'(B)=\frac{1}{B}【導數和牛頓迭代】裏面有提到過一點,這裏是把AA當做常數捨去了)

       \ \ \ \ \ \ \,那我們現在把牛頓迭代的公式化簡:

B(x)=B(x1)F(B(x1))×B(x1)=B(x1)B(x1)×F(B(x1))=B(x1)B(x1)×(ln(B(x1))A)=B(x1)×(1ln(B(x1))+A)\begin{aligned} B(x)& =B(x-1)-F\left(B(x-1)\right)\times B(x-1)\\& =B(x-1)-B(x-1)\times F\left(B(x-1)\right)\\& =B(x-1)-B(x-1)\times \left(\ln \left(B(x-1)\right)-A\right)\\& =B(x-1)\times \left(1-\ln \left(B(x-1)\right)+A \right) \end{aligned}

       \ \ \ \ \ \ \,再次強調B後面的括號的迭代版本的意思,不是多項式的項。

       \ \ \ \ \ \ \,現在看似分治可做,我們用兩個容器相互裝版本。每次老版本一卷,新版本長度就會倍增,所以說我們做 logn\log n 次迭代就好。我們的操作相當於把式子拆了求收斂值,所以不會有精度的問題,求出來就好了。

       \ \ \ \ \ \ \,那麼現在的問題是,第一個版本是怎麼樣,洛咕模板給的是保證 A0=0A_0=0,因爲e0=1e^0=1,也就是exp(0)=1exp(0)=1,所以說 B0=1B_0=1,也就是常數項爲 11

       \ \ \ \ \ \ \,當然了,同理,他一般會保證A0=0A_0=0,我們不方便找到其他exp(A0)exp(A_0)模的意義下的值。如果可以算的話,可以在模板裏面傳入 ConstantConstant 也就是 exp(A0)exp(A_0) 的值。

       \ \ \ \ \ \ \,否認A0A_0不等於00,完全不能求 expexp 的說法。

inline Polynomial Exponential(const Polynomial &a,int Constant=1){
	Polynomial ret,D;int ed=a.size();
	ret.resize(1);ret[0]=Constant;
	for(int len=2;len<=ed;len<<=1){
	  	D=Logarithmic(ret);D.resize(len);
	  	D[0]=(1ll*a[0]+1ll-D[0]+mod)%mod;
	  	for(int i=1;i<len;++i) D[i]=(1ll*a[i]-D[i]+mod)%mod;
		int n=Prepare_Transformation(len<<1);
	  	ret.resize(n);D.resize(n);
	  	NTT(ret,1);NTT(D,1);
	  	for(int i=0;i<n;i++)ret[i]=1ll*ret[i]*D[i]%mod;
	  	NTT(ret,-1);
	  	for(int i=len;i<(len<<1);++i)ret[i]=D[i]=0;
	}
	ret.resize(ed);
	return ret;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章