码迷,mamicode.com
首页 > 其他好文 > 详细

多项式除法

时间:2019-12-20 21:09:16      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:前置   play   除法   define   def   font   std   resize   blog   

多项式除法

定义

\(给一n次多项式F(x),m次多项式G(x),求一多项式Q(x),R(x),满足\)

  • \(Q(x)次数为n-m,R(x)次数小于m\)
  • \(F(x)=G(x)Q(x)+R(x)\)

前置知识

推式子:

\[令f_r(x)表示函数f(x)系数翻转后的函数\]
\[\because F(x)=a_0x^n+a_1x^{n-1}+...a_n\]
\[\therefore F_r(x)=a_nx^n+a_{n-1}x^{n-1}+...a_0\]
\[=x^n(a_n+a_{n-1}\frac{1}{x}+...a_0\frac{1}{x^n})\]
\[=x^nF(\frac{1}{x})\]
\[\because F(x)=G(x)Q(x)+R(x)\]
\[\therefore F(\frac{1}{x})=G(\frac{1}{x})Q(\frac{1}{x})+R(\frac{1}{x})\]
\[左右同乘x^n\]
\[\because x^nF(\frac{1}{x})=x^mG(\frac{1}{x})x^{n-m}Q(\frac{1}{x})+x^{n-m+1}x^{m-1}R(\frac{1}{x})\]
\[\therefore F_r(\frac{1}{x})=G_r(\frac{1}{x})Q_r(\frac{1}{x})+x^{n-m+1}R(\frac{1}{x})\]
\[\because F_r(\frac{1}{x})\equiv G_r(\frac{1}{x})Q_r(\frac{1}{x})+x^{n-m+1}R(\frac{1}{x})\ (mod\ x^{n-m+1})\]
\[\therefore F_r(\frac{1}{x})\equiv G_r(\frac{1}{x})Q_r(\frac{1}{x})\ (mod\ x^{n-m+1})\]
\[\because F_r(x)\equiv G_r(x)Q_r(x)\ (mod\ x^{n-m+1})\]
\[\therefore \frac{F_r(x)}{G_r(x)}\equiv Q_r(x)\ (mod\ x^{n-m+1})\]

步骤:

\(1.求出G_r(x)在mod\ x^{n-m+1}意义下的逆元,与F_r(x)相乘\)

\(2.翻转\)

【模板】多项式除法

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

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
# define read read1<int>()
# define Type template<typename T>
Type inline T read1(){
    T n=0;
    char k;
    bool fl=0;
    do (k=getchar())=='-'&&(fl=1);while('9'<k||k<'0');
    while(47<k&&k<58)n=(n<<3)+(n<<1)+(k^48),k=getchar();
    return fl?-n:n;
}
# define f(i,l,r) for(int i=(l);i<=(r);++i)
# define fre(k) freopen(k".in","r",stdin);freopen(k".ans","w",stdout)
# define ll int64_t
class Array{
    private:
        vector<int>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());}
};
Array operator -(Array a,Array b){
    int N=a.size(),M=b.size();
    Array t;
    for(int i=0;i<N&&i<M;++i)
        t.push((i<N?a[i]:0)-(i<M?b[i]:0));
    return t;
}
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)<<L-1);
    }
    f(i,0,len-1)
        if(i<r[i])swap(a[i],a[r[i]]);
    for(int i=1;i<len;i<<=1){
        int T=qkpow(Ty?g:332748118,(mod-1)/(i<<1),mod);
        for(int W=i<<1,j=0;j<len;j+=W){
            ll omega=1;
            for(int k=0;k<i;++k,omega=omega*T%mod){
                ll x(a[j+k]),y(omega*a[i+j+k]%mod);
                a[j+k]=x+y;(a[j+k]>mod)&&(a[j+k]-=mod);
                a[i+j+k]=x-y+mod;(a[i+j+k]>mod)&&(a[i+j+k]-=mod);
            }
        }
    }
    return r;
}
Array operator * (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)x[i]*y[i]%mod;
    NTT(limit,x,0,r);
    int tem=qkpow(limit,mod-2,mod);
    f(i,0,n+m)ans.push((ll)x[i]*tem%mod);
    return ans;
}
Array& operator *= (Array& x,Array y){
    return x=x*y;
}
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 operator / (Array x,Array y){
    int N=x.size()-1,M=y.size()-1;
    if(N<M)return Array(1,0);
    x.swap();y.swap();
    y.resize(N-M+1);
    Array t=Inv(y)*x;
    t.resize(N-M+1);
    t.swap();
    return t;
}
Array F,G,x;
int n,m;
int main(){
    n=read;m=read;
    for(int i=0;i<=n;++i)F.push(read);
    for(int i=0;i<=m;++i)G.push(read);
    x=F/G;
    for(int i=0;i<n-m+1;++i)printf("%d ",x[i]);
    putchar('\n');
    x=F-G*x;
    for(int i=0;i<m;++i)printf("%d ",(mod+x[i])%mod);
    return 0;
}

多项式除法

标签:前置   play   除法   define   def   font   std   resize   blog   

原文地址:https://www.cnblogs.com/SYDevil/p/12074661.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!