日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

多项式的求逆、取模和多点求值学习小记

發(fā)布時(shí)間:2025/3/15 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多项式的求逆、取模和多点求值学习小记 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 最近學(xué)習(xí)了多項(xiàng)式的求逆、取模和多點(diǎn)求值,這些方法能夠解決很多多項(xiàng)式問(wèn)題。

  • 這三個(gè)操作是環(huán)環(huán)相扣的,很有趣,學(xué)完后不妨記錄一下。

多項(xiàng)式求逆

  • 給出一個(gè)次數(shù)界為 nnn 的多項(xiàng)式 A(x)A(x)A(x) ,需要求 B(x)B(x)B(x) 滿足: A(x)B(x)≡1(modxn)A(x)B(x)\equiv1(mod\ x^n)A(x)B(x)1(mod?xn)

  • 我們考慮倍增來(lái)求解,假設(shè)我們已經(jīng)知道 G(x)G(x)G(x) 滿足:A(x)G(x)≡1(modx?n2?)A(x)G(x)\equiv1(mod\ x^{\lfloor\frac{n}{2}\rfloor})A(x)G(x)1(mod?x?2n??)

  • 那么開始推導(dǎo),兩式相減:B(x)?G(x)≡0(modx?n2?)B(x)-G(x)\equiv0(mod\ x^{\lfloor\frac{n}{2}\rfloor})B(x)?G(x)0(mod?x?2n??)

  • 兩邊平方:B(x)2+G(x)2?2G(x)B(x)≡0(modxn)B(x)^2+G(x)^2-2G(x)B(x)\equiv0(mod\ x^n)B(x)2+G(x)2?2G(x)B(x)0(mod?xn)

  • 兩邊同乘 A(x)A(x)A(x)B(x)+A(x)G(x)2?2G(x)≡0(modxn)B(x)+A(x)G(x)^2-2G(x)\equiv0(mod\ x^n)B(x)+A(x)G(x)2?2G(x)0(mod?xn)

  • 于是可求得 B(x)B(x)B(x)B(x)≡2G(x)?A(x)G(x)2(modxn)B(x)\equiv2G(x)-A(x)G(x)^2(mod\ x^n)B(x)2G(x)?A(x)G(x)2(mod?xn)

  • 當(dāng)遞歸至 n=1n=1n=1 時(shí)則有:B(0)=A(0)?1B(0)=A(0)^{-1}B(0)=A(0)?1

  • 那么我們開始時(shí)就次數(shù)界 nnn 配成 2k2^k2k 的形式,直接做倍增即可完成求逆。

  • 時(shí)間復(fù)雜度 O(nlogn)O(n\ log\ n)O(n?log?n)

  • 模板題:洛谷 P4238 【模板】多項(xiàng)式求逆

多項(xiàng)式取模

  • 多項(xiàng)式取模是依賴于多項(xiàng)式求逆的。

  • 給出一個(gè)次數(shù)為 nnn 的多項(xiàng)式 A(x)A(x)A(x) ,一個(gè)次數(shù)為 m(m≤n)m(m\leq n)m(mn) 的多項(xiàng)式 B(x)B(x)B(x)

  • 我們需要求出多項(xiàng)式 C(x)C(x)C(x)R(x)R(x)R(x) 滿足:A(x)=B(x)C(x)+R(x)(?)A(x)=B(x)C(x)+R(x)\ \ \ \ \ \ (*)A(x)=B(x)C(x)+R(x)??????(?)

  • 其中 C(x)C(x)C(x) 的次數(shù) ≤n?m\leq n-mn?mR(x)R(x)R(x) 的次數(shù) &lt;m&lt;m<m

  • 考慮一個(gè)翻轉(zhuǎn)操作:AR(x)=xnA(1x)A^R(x)=x^nA(\frac{1}{x})AR(x)=xnA(x1?)

  • 其實(shí)質(zhì)就是多項(xiàng)式的系數(shù)翻轉(zhuǎn)過(guò)來(lái)。

  • (?)(*)(?) 式兩邊同乘 xnx^nxn 、并令 x=1xx=\frac{1}{x}x=x1? 代入,可得:xnA(1x)=xmB(1x)?xn?mC(1x)+xn?m+1xm?1R(1x)x^nA(\frac{1}{x})=x^mB(\frac{1}{x})·x^{n-m}C(\frac{1}{x})+x^{n-m+1}x^{m-1}R(\frac{1}{x})xnA(x1?)=xmB(x1?)?xn?mC(x1?)+xn?m+1xm?1R(x1?)

  • 則有:AR(x)=BR(x)CR(x)+xn?m+1RR(x)A^R(x)=B^R(x)C^R(x)+x^{n-m+1}R^R(x)AR(x)=BR(x)CR(x)+xn?m+1RR(x)

  • 關(guān)鍵一步來(lái)了,把上式放在 (modxn?m+1)(mod\ x^{n-m+1})(mod?xn?m+1) 下,就能消除 RR(x)R^R(x)RR(x) 的影響(并且對(duì) CR(x)C^R(x)CR(x) 無(wú)影響,其每一項(xiàng)次數(shù)都 ≤n?m\leq n-mn?m):AR(x)≡BR(x)CR(x)(modxn?m+1)A^R(x)\equiv B^R(x)C^R(x)\ \ (mod\ x^{n-m+1})AR(x)BR(x)CR(x)??(mod?xn?m+1)

  • 于是我們通過(guò)多項(xiàng)式求逆可以算出 CR(x)C^R(x)CR(x)CR(x)≡AR(x)BR(x)(modxn?m+1)C^R(x)\equiv \frac{A^R(x)}{B^R(x)}\ \ (mod\ x^{n-m+1})CR(x)BR(x)AR(x)???(mod?xn?m+1)

  • 之后翻轉(zhuǎn)得到 C(x)C(x)C(x) ,回代 (?)(*)(?) 式求出 R(x)R(x)R(x) 即可!

  • 以上各操作均是 O(nlogn)O(n\ log \ n)O(n?log?n) 的。

  • 模板題:洛谷 P4512 【模板】多項(xiàng)式除法

多項(xiàng)式多點(diǎn)求值

  • 多點(diǎn)求值需要用到多項(xiàng)式取模!

  • 給出一個(gè) nnn 次多項(xiàng)式 F(x)F(x)F(x) ,和 mmm 個(gè)值 x1,x2,???,xmx_1,x_2,···,x_mx1?,x2?,???,xm? ,要求 F(x1),F(x2),???,F(xm)F(x_1),F(x_2),···,F(x_m)F(x1?),F(x2?),???,F(xm?)

  • 比較關(guān)鍵的一個(gè)性質(zhì)F(x)mod(x?a)=F(a)F(x)\ mod\ (x-a)=F(a)F(x)?mod?(x?a)=F(a)

  • 用因式定理或者直接將 (x?a+a)k(x-a+a)^k(x?a+a)k 二項(xiàng)式展開都能很容易得到。

  • 那么我們依據(jù)這個(gè)來(lái)分治解決本問(wèn)題。

  • L(x)=∑i=1?n2?(x?xi)L(x)=\sum_{i=1}^{\lfloor\frac{n}{2}\rfloor}(x-x_i)L(x)=i=1?2n???(x?xi?)R(x)=∑i=?n2?+1n(x?xi)R(x)=\sum_{i=\lfloor\frac{n}{2}\rfloor+1}^{n}(x-x_i)R(x)=i=?2n??+1n?(x?xi?)

  • 那么對(duì)于 1≤i≤?n2?1\leq i\leq\lfloor\frac{n}{2}\rfloor1i?2n??F(xi)=(FmodL)(xi)F(x_i)=(F\ mod\ L)(x_i)F(xi?)=(F?mod?L)(xi?) ;對(duì)于 ?n2?+1≤i≤n\lfloor\frac{n}{2}\rfloor+1\leq i\leq n?2n??+1inF(xi)=(FmodR)(xi)F(x_i)=(F\ mod\ R)(x_i)F(xi?)=(F?mod?R)(xi?)。(原理同上述性質(zhì)

  • 于是我們向線段樹一樣往下分治計(jì)算即可。

  • 具體來(lái)說(shuō)就是先預(yù)處理出每個(gè)區(qū)間的 ∏i=lr(x?xi)\prod_{i=l}^r(x-x_i)i=lr?(x?xi?) (相當(dāng)于是求出 L,RL,RL,R ,自下而上),

  • 之后再自上而下地把 F(x)F(x)F(x) 往下傳,每次就模 LLLRRR 并分別傳向左右子區(qū)間。

  • 當(dāng)分治到底層(l=rl=rl=r)的時(shí)候,F(x)F(x)F(x) 就是被模剩一個(gè)常數(shù)項(xiàng) F′(0)F&#x27;(0)F(0) 了,直接就有 F(xi)=F′(0)F(x_i)=F&#x27;(0)F(xi?)=F(0)

  • 每次做多項(xiàng)式取模是 O(nlogn)O(n\ log\ n)O(n?log?n) 的,套上分治就是 O(nlog2n)O(n\ log^2n)O(n?log2n) 的了。當(dāng)然常數(shù)很大……

  • 模板題:洛谷 P5050 【模板】多項(xiàng)式多點(diǎn)求值

  • 這里給出這題的代碼:

#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespace std; typedef long long LL; const int N=64005,M=16,G=3,mo=998244353; int tot; int f[N],p[N],ans[N]; int mul[N*M<<1],st[N<<2],en[N<<2]; int g[N*M<<1],stg[N<<2],eng[N<<2]; int a[N],b[N],c[N],rr[N];//a=b*c+rr int ra[N],rb[N<<1],irb[N<<2]; int f1[N<<2],f2[N<<2],rev[N<<2],wn[N<<2]; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } void write(int x) {if(x>9) write(x/10);putchar(x%10+'0'); } inline int ksm(int x,int y) {int s=1;while(y){if(y&1) s=(LL)s*x%mo;x=(LL)x*x%mo;y>>=1;}return s; } inline void NTT(int *y,int len,int ff) {for(int i=0;i<len;i++)if(i<rev[i]) swap(y[i],y[rev[i]]);for(int h=2,d=len>>1;h<=len;h<<=1,d>>=1)for(int i=0,k=h>>1;i<len;i+=h)for(int j=0,cnt=0;j<k;j++,cnt+=d){int u=y[i+j],t=(LL)wn[cnt]*y[i+j+k]%mo;y[i+j]=u+t>=mo?u+t-mo:u+t;y[i+j+k]=u-t<0?u-t+mo:u-t;}if(ff==-1){for(int i=len>>1;i;i--) swap(y[i],y[len-i]);int inv=ksm(len,mo-2);for(int i=0;i<len;i++) y[i]=(LL)y[i]*inv%mo;} } void solve(int len,int num) {if(len==1){irb[0]=ksm(rb[0],mo-2);return;}solve(len>>1,num-1);for(int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|(i&1)<<num-1;int w0=ksm(G,(mo-1)/len);for(int i=wn[0]=1;i<=len;i++) wn[i]=(LL)wn[i-1]*w0%mo;for(int i=0;i<len>>1;i++) f1[i]=rb[i];NTT(f1,len,1),NTT(irb,len,1);for(int i=0;i<len;i++) f1[i]=(2-(LL)f1[i]*irb[i]%mo+mo)*irb[i]%mo;NTT(f1,len,-1);for(int i=0;i<len>>1;i++) irb[i]=f1[i];for(int i=len>>1;i<len;i++) irb[i]=0; } void make(int v,int l,int r) {if(l==r){st[v]=++tot;mul[tot]=mo-p[l];en[v]=++tot;mul[tot]=1;return;}int mid=l+r>>1,ls=v<<1,rs=ls|1;make(ls,l,mid);make(rs,mid+1,r);int na=en[ls]-st[ls]+1,nb=en[rs]-st[rs]+1;int len=1,ll=0;while(len<na+nb) len<<=1,ll++;for(int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|(i&1)<<ll-1;int w0=ksm(G,(mo-1)/len);for(int i=wn[0]=1;i<=len;i++) wn[i]=(LL)wn[i-1]*w0%mo;for(int i=0;i<na;i++) f1[i]=mul[st[ls]+i];for(int i=na;i<len;i++) f1[i]=0;for(int i=0;i<nb;i++) f2[i]=mul[st[rs]+i];for(int i=nb;i<len;i++) f2[i]=0;NTT(f1,len,1),NTT(f2,len,1);for(int i=0;i<len;i++) f1[i]=(LL)f1[i]*f2[i]%mo;NTT(f1,len,-1);na+=nb;while(na>1 && !f1[na-1]) na--;st[v]=tot+1;for(int i=0;i<na;i++) mul[++tot]=f1[i];en[v]=tot; } void find(int v,int l,int r,int fa) {int na=eng[fa]-stg[fa],nb=en[v]-st[v];if(na>=nb){for(int i=0;i<=na;i++) a[i]=g[stg[fa]+i];for(int i=0;i<=nb;i++) b[i]=mul[st[v]+i];for(int i=0;i<=na-nb;i++) ra[i]=a[na-i];for(int i=0;i<=nb;i++) rb[i]=b[nb-i];for(int i=na-nb+1;i<=nb;i++) rb[i]=0;int len=1,ll=0;while(len<(na-nb+1)*2) len<<=1,ll++;for(int i=0;i<len;i++) f1[i]=0;solve(len,ll);for(int i=0;i<=na-nb;i++) f1[i]=ra[i],f2[i]=irb[i];for(int i=na-nb+1;i<len;i++) f1[i]=f2[i]=0;NTT(f1,len,1),NTT(f2,len,1);for(int i=0;i<len;i++) f1[i]=(LL)f1[i]*f2[i]%mo;NTT(f1,len,-1);for(int i=0;i<=na-nb;i++) c[na-nb-i]=f1[i];len=1,ll=0;while(len<nb<<1) len<<=1,ll++;for(int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|(i&1)<<ll-1;int w0=ksm(G,(mo-1)/len);for(int i=wn[0]=1;i<=len;i++) wn[i]=(LL)wn[i-1]*w0%mo;for(int i=0;i<nb;i++) f1[i]=b[i],f2[i]=c[i];for(int i=nb;i<len;i++) f1[i]=f2[i]=0;NTT(f1,len,1),NTT(f2,len,1);for(int i=0;i<len;i++) f1[i]=(LL)f1[i]*f2[i]%mo;NTT(f1,len,-1);for(int i=0;i<nb;i++) rr[i]=(a[i]-f1[i]+mo)%mo;for(int i=0;i<=max(na,nb);i++) a[i]=b[i]=c[i]=ra[i]=rb[i]=irb[i]=0;while(nb>1 && !rr[nb-1]) nb--;stg[v]=tot+1;for(int i=0;i<nb;i++) g[++tot]=rr[i],rr[i]=0;eng[v]=tot;}else{stg[v]=tot+1;for(int i=stg[fa];i<=eng[fa];i++) g[++tot]=g[i];eng[v]=tot;}if(l==r){ans[l]=g[stg[v]];return;}int mid=l+r>>1;find(v<<1,l,mid,v);find(v<<1|1,mid+1,r,v); } int main() {int n=read(),m=read();for(int i=0;i<=n;i++) f[i]=read();for(int i=1;i<=m;i++) p[i]=read();make(1,1,m);stg[tot=0]=1;for(int i=0;i<=n;i++) g[++tot]=f[i];eng[0]=tot;find(1,1,m,0);for(int i=1;i<=m;i++) write(ans[i]),putchar('\n');return 0; }

總結(jié)

以上是生活随笔為你收集整理的多项式的求逆、取模和多点求值学习小记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。