1. 程式人生 > 實用技巧 >多項式求逆

多項式求逆

多項式求逆

洛谷P4238 【模板】多項式乘法逆 程式碼

\[B=2b-b^2A \]

P.S.

  • 模板
//Poly
const int G=3,iG=Pow(G,mod-2);
vector<int> rev;
void NTT(vector<int>&f,int t){
    int n=sz(f);
    for(int i=0;i<n;i++)if(i<rev[i]) swap(f[i],f[rev[i]]);
    for(int mid=1;mid<n;mid<<=1){
        int wn=Pow(~t?G:iG,(mod-1)/(mid<<1));
        for(int j=0;j<n;j+=(mid<<1))
            for(int w=1,k=j;k<mid+j;w=(ll)w*wn%mod,k++){
                int x=f[k],y=(ll)w*f[mid+k]%mod;
                f[k]=(x+y)%mod,f[mid+k]=(x-y+mod)%mod;
            }
    }
    if(!~t){
        int in=Pow(n,mod-2);
        for(int i=0;i<n;i++) f[i]=(ll)f[i]*in%mod;
    }
}
void Mulpoly(vector<int>&a,vector<int> b){
    int n=sz(a),m=sz(b),lim=1<<int(ceil(log2(n+m)));
    rev.resize(lim),a.resize(lim),b.resize(lim);
    for(int i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
    NTT(a,1),NTT(b,1);
    for(int i=0;i<lim;i++) a[i]=(ll)a[i]*b[i]%mod;
    NTT(a,-1),a.resize(n+m-1);
}
void Invpoly(vector<int>&a,vector<int>&inv){
    int n=sz(a),t=0,now=2;
    vector<int> b[2],ma={a[0],a[1]};
    b[t].assign(now,0),b[t][0]=Pow(a[0],mod-2);
    while(now<n){
        t^=1,now=(now<<1)-1;
        b[t].assign(now,0);
        for(int i=0;i<((now+1)>>1);i++) b[t][i]=(ll)2*b[t^1][i]%mod;
        for(int i=((now+1)>>1);i<now;i++) ma.pb(i<n?a[i]:0);
        Mulpoly(b[t^1],b[t^1]),Mulpoly(b[t^1],ma);
        for(int i=0;i<now;i++) (b[t][i]+=mod-b[t^1][i])%=mod;
    }
    for(int i=0;i<n;i++) inv[i]=b[t][i];
}