多项式乘法逆

多项式乘法逆

定义

\(对于多项式F(x),求一多项式F^{-1}(x),使得F(x)F^{-1}(x)\equiv 1(mod\ x^n).\\系数对P取模(通常为998244353等原根为2,3的较大的)质数\)

前置知识

  • \(NTT\)
  • \(逆元\)
  • \(多项式相关\)
  • \(同余\)

推式子:

\[ 假设已经求出(mod\ x^{\lceil \frac{n}{2} \rceil})意义下的F(x)的逆元F_0^{-1}(x) \]
\[ \because F(x)F_0^{-1}(x) \equiv 1(mod\ x^{\lceil \frac{n}{2} \rceil}) \]
\[ 又\because F(x)F^{-1}\equiv1(mod\ x^n) \]
\[ \therefore F(x)(F_0^{-1}(x)-F^{-1}(x))\equiv 0(mod\ x^{\lceil \frac{n}{2} \rceil}) \]
\[ \therefore F_0^{-1}(x)-F^{-1}(x)\equiv 0(mod\ x^{\lceil \frac{n}{2} \rceil}) \]
\[ \because (F_0^{-1}(x)-F^{-1}(x))^2\equiv 0(mod\ x^n) \]
\[ \therefore (F_0^{-1}(x))^2-2F_0^{-1}(x)F^{-1}(x)+(F^{-1}(x))^2\equiv 0(mod\ x^n) \]
\[ \because F(x)(F_0^{-1}(x))^2-2F(x)F_0^{-1}(x)F^{-1}(x)+F(x)(F^{-1}(x))^2\equiv 0(mod\ x^n) \]
\[ \because F(x)F_0^{-1}(x)^2-2F_0^{-1}(x)+F^{-1}(x)\equiv 0(mod\ x^n) \]
\[ \therefore F^{-1}(x)\equiv F_0^{-1}(x)(2-F(x)F_0^{-1}(x))(mod\ x^n) \]

步骤:

\(1. 分治\)

\(2. NTT求乘积\)

\[ \\ \]

【模板】多项式乘法逆

\[ \\ \]

\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)

#include
#include
#include
#include
using namespace std;
# define read read1()
# define Type template
Type inline T read1(){
    T n=0;
    char k;
    bool fl=0;
    do (k=getchar())=='-'&&(fl=1);while('9'a;
    public:
        Array(const int size,const int f):a(size,f){}
        void push(int n){a.push_back(n);}
        Array(int* l=NULL,int* r=NULL){while(l!=r)push(*l),++l;}
        inline int size(){return a.size();}
        inline int& operator [] (const int x){return a[x];}
        void resize(int n){a.resize(n);}
        void clear(){a.clear();}
        void swap(){reverse(a.begin(),a.end());}
};
int qkpow(int b,int m,int mod){
    int tem=b,ans=1;
    for(;m;m>>=1,tem=(ll)tem*tem%mod)
        if(m&1)ans=(ll)ans*tem%mod;
    return ans;
}
const int mod=998244353,g=3;
int* NTT(const int len,Array& a,const bool Ty,int* r=NULL){
    if(!r){
        r=new int[len];
        r[0]=0;int L=log2(len);
        f(i,0,len-1)
            r[i]=(r[i>>1]>>1)|((i&1)<mod)&&(a[j+k]-=mod);
                a[i+j+k]=x-y+mod;(a[i+j+k]>mod)&&(a[i+j+k]-=mod);
            }
        }
    }
    return r;
}
void Rev(Array &x,Array y){
    int n=x.size()-1,m=y.size()-1;
    int limit=1;
    while(limit<=n+m)limit<<=1;
    Array ans;
    x.resize(limit+1);
    y.resize(limit+1);
    int *r;
    r=NTT(limit,x,1);
    NTT(limit,y,1,r);
    f(i,0,limit)x[i]=(ll)(2ll-(ll)x[i]*y[i]%mod+mod)%mod*y[i]%mod;
    NTT(limit,x,0,r);
    int tem=qkpow(limit,mod-2,mod);
    f(i,0,n+m)x[i]=(ll)x[i]*tem%mod;
    x.resize(n+m+1);
}
Array Inv(Array a){
    int N=a.size();
    if(N==1)return Array(1,qkpow(a[0],mod-2,mod));
    Array b=a;b.resize(N+1>>1);
    b=Inv(b);b.resize(N);
    Rev(a,b);
    a.resize(N);
    return a;
}
Array x;
int n;
int main(){
    n=read;
    for(int i=0;i

你可能感兴趣的:(多项式乘法逆)