多項式的大坑

發現自己以前老是挑題做。。
看到多項式就跑了。。主要是以前學不會啊。。
現在要逼自己一把。。再一次開這個大坑
主要是卡在題上了
同時感覺自己智商有所提升。。理解起來也比以前好。。
以前看多項式求逆看來看去看不懂在幹什麼。。
操作可能不會一次學全。。需要的時候再點亮技能樹再點吧
順便這個是可以給我存模板的。。
當然,會附上學習資料。。
主要是爲了以後忘了的時候看的。。這種東西當然忘得快
大部分題都可以在洛谷找到模板題。。

一些需要注意的點

基本上都是在2n2^n​下操作的
一般都是4倍空間,巨大常數

泰勒展開式

一開始一直不敢看。。
知乎上寫得挺好的
我個人喜歡第二個當然不是因爲圖
比較通用的形式是這個
在這裏插入圖片描述
但其實我們一般取的都是x0=0x0=0時的泰勒展開式,所以更多的時候,他的形式是這樣的
在這裏插入圖片描述
一些需要知道,或者說做題的時候比較常用的泰勒展開式
別的大多數都可以在這些的基礎上,通過換元或者相乘的方法弄出來
1+x+x2+x3.......xn=1xn+11x1+x+x^2+x^3.......x^n=\frac{1-x^{n+1}}{1-x}
其實就是等比數列求和,考慮級數收斂,當n趨近於無限大的時候就是11x\frac{1}{1-x}
1+x+x22!+x33!+x44!+......+xnn!+....=ex1+x+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}+......+\frac{x^n}{n!}+....=e^x
exe^x的泰勒展開式其實也很簡單,因爲他取的是0這個地方的導啊,並且exe^x怎麼導都是exe^x
暫時我只會n趨近於無限大的。。這個式子的意義自己思考一下?舉幾個栗子可能就明白了
ln(1+x)=xx22+x33x44+x55........ln(1+x)=x-\frac{x^2}{2}+\frac{x^3}{3}-\frac{x^4}{4}+\frac{x^5}{5}-........
容易推導ln(1x)ln(1-x)的泰勒展開,就是把xx換爲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&#x27;(x)就是直接求導就可以了,因爲都是axia*x^i的形式所以很好搞
然後就是一個多項式求逆
最後就是按求導的方法導回去就就可以了

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