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

多项式最基础的操作

时间:2018-08-05 21:37:12      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:...   static   ceil   变换   code   amp   isp   次数   保留   

多项式乘法

时间复杂度\(O(n\ log\ n)\)

const int P = 998244353;
inline int Pow(ll x, int y=P-2){
    ll ass=1;
    for(; y; y>>=1, x=x*x%P) if(y&1) ass=ass*x%P;
    return ass;
}
inline int Mod(int x){ return x<P?x:x-P;}
inline void NTT(int *f, int g){
    for(int i=0, j=0; i<p; ++i){
        if(i>j) swap(f[i], f[j]);
        for(int k=p>>1; (j^=k)<k; k>>=1);
    }
    for(int i=1; i<p; i<<=1){
        int w0=(g==1?Pow(3, (P-1)/i/2):Pow(Pow(3, (P-1)/i/2)));
        for(int j=0; j<p; j+=i<<1){
            int w=1;
            for(int k=j; k<j+i; ++k){
                int t=(ll)w*f[k+i]%P;
                f[k+i]=Mod(P+f[k]-t);
                f[k]=Mod(f[k]+t);
                w=(ll)w*w0%P;
            }
        }
    }
    if(g==-1) for(int i=0, I=Pow(p); i<p; ++i) f[i]=(ll)f[i]*I%P;
}
..............

多项式求逆

给定多项式\(A(x)\),求\(A^{-1}(x)\)满足\[A(x)A^{-1}(x)\equiv 1\pmod{x^n}\]

其中\(\pmod{x^n}\)即为舍去次数\(\ge n\)的项,只保留\(0\)\(n-1\)次项

考虑倍增

\(n=1\)时只有常数项,答案可以直接快速幂求出

假设当前已经求出\(\pmod{x^{\lceil \frac{n}{2} \rceil}}\)意义下的\(A(x)\)的逆元\(B'(x)\),满足\[A(x)B'(x)\equiv 1\pmod{x^{\lceil \frac{n}{2} \rceil}}\]

需要求\(B(x)\)满足\[A(x)B(x)\equiv 1\pmod{x^n}\]

两式相减得\[A(x)(B(x)-B'(x))\equiv 0\pmod{x^{\lceil \frac{n}{2} \rceil}}\]

\[B(x)-B'(x)\equiv0\pmod{x^{\lceil \frac{n}{2} \rceil}}\]

平方得\[B^2(x)-2B(x)B'(x)+B'^2(x)\equiv0\pmod{x^n}\]

由于一个多项式平方之后,次数\(<n\)的项至少是由原先一个次数\(<\lceil \frac{n}{2} \rceil\)的项乘上其他项得到的,所以这个结果的\(0\)\(n-1\)次系数仍然是\(0\),可以变成\(\pmod{x^n}\)

同乘\(A(x)\)\[B(x)-2B'(x)+A(x)B'^2(x)\equiv0\pmod{x^n}\]

\[B(x)\equiv B'(x)(2-A(x)B'(x))\pmod{x^n}\]

其中多项式乘法可以使用快速傅里叶变换加速

时间复杂度\[T(n)=T(\frac{n}{2})+O(n\ log\ n)=O(n\ log\ n)\]

inline void polyinv(int n, int *a, int *b){
    if(n==1) return (void)(b[0]=Pow(a[0]));
    polyinv((n+1)/2, a, b);
    static int tmp[N];
    for(p=1; p<n*2-1; p<<=1);
    memcpy(tmp, a, n<<2), memset(tmp+n, 0, p-n<<2);
    NTT(tmp, 1), NTT(b, 1);
    for(int i=0; i<p; ++i) b[i]=(2-(ll)b[i]*tmp[i]%P+P)*b[i]%P;
    NTT(b, -1);
    memset(b+n, 0, p-n<<2);
}

(未完)

多项式最基础的操作

标签:...   static   ceil   变换   code   amp   isp   次数   保留   

原文地址:https://www.cnblogs.com/CMXRYNP/p/9426916.html

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