多項式求逆與多項式除法/取模
多項式求逆
Procedure
多項式求逆是多項式模組中的一個重要操作(“操作”這個詞看出如今多項式題是多麼的工業化,猶如毒瘤8操作LCT),在做生成函式/多項式除法、多項式取模/多項式多點求值等中均有應用
對於一個n次多項式
,我們希望求出一個m-1次多項式
,滿足
也就是說,
為
在模
意義下的逆(即
以後的項我們都不管了,前面的項乘起來只有常數項係數為1,其他係數都是0)
多項式求逆運用了倍增的思想
假設我們已經求出了
考慮如何求
移項
此時意味著
的0 ~ m/2-1次項的係數全都是0,那麼將同餘式兩邊平方,就變成0 ~ m-1次項的係數都為0
因此
展開
提一個
出來
此時容易看出
這樣就求出了
模
意義下的乘法逆元
我們從m=1開始做,此時直接求常數項的乘法逆元即可,
然後可以推出m=2,4,8,16…
這樣一直倍增下去,直到m>=我們所需要的次數,此時直接取前面我們需要的項,後面多出來的直接設為0即可(模掉了沒有影響)
注意,由於我們求 是在模 意義下進行的,而不是 ,因此即使 的次數為m/2-1,此時的 的次數仍然要取m-1
分析時間複雜度
(常數相當大)
Code
void make(int l,LL *a,LL *b)//l為我們需要的次數,a為待求逆多項式,用b來儲存結果
{
b[0]=ksm(a[0],mo-2);//求常數項逆元
for(int m=1,t=2,num=4,cnt=2;m<l;m=t,t=num,num<<=1,cnt++)
//由於乘法有平方操作,因此NTT的範圍需要開到2倍。
//t為當前的模數次數,m=t/2
{
prp(num,cnt);//預處理單位根、反位等
fo(i,0,m-1) c[i]=a[i],d[i]=b[i];
fo(i,m,t-1) c[i]=a[i];
fo(i,t,num-1) c[i]=0;
NTT(c,0,num),NTT(b,0,num);
fo(i,0,num-1) b[i]=b[i]*b[i]%mo*c[i]%mo;
NTT(b,1,num);
fo(i,0,t-1) b[i]=((LL)2*d[i]-b[i]+mo)%mo;
fo(i,t,num-1) b[i]=0;
}
}
多項式除法(多項式取模)
Procedure
多項式除法/取模也是多項式模組中的一個重要操作,在做生成函式/多項式多點求值等中均有應用。。。
對於一個n次多項式
,m次多項式
(n>=m),我們希望求出一個n-m次多項式
,一個至多m-1次的多項式
,滿足
,並且
小於
當