zoukankan      html  css  js  c++  java
  • 【模板】多项式求逆

    题目描述

    题解:

    多项式$O(nlogn)$全家桶里面比较简单比较基础的一个。

    考虑到已知$F(x)$我们要求$G(x)$满足$F(x)*G(x)=1(mod x^k)$,

    首先,当$k==1$时,求一下$F(0)$逆元即可。

    然后看看$mod x^k$能不能从$mod x^{k/2}$搞出来。

    假设有$F(x)*H(x)=1(mod x^{k/2})$

    那么$G(x)-H(x)=0(mod x^{k/2})$

    平方,有$G^{2}(x)+H^{2}(x)-2*G(x)*H(x)=0(mod x^k)$

    乘个$F$,有$G(x)+F(x)*H^{2}(x)-2*H(x)=0(mod x^k)$

    剩下的递归。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MOD = 998244353;
    const int N = 100050;
    typedef long long ll;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    struct node
    {
        int len;
        ll s[N];
        node(){memset(s,0,sizeof(s));}
        void print(int n)
        {
            for(int i=0;i<n;i++)printf("%d ",s[i]);
            puts("");
        }
    }las,now;
    ll fastpow(ll x,int y)
    {
        ll ret = 1;
        while(y)
        {
            if(y&1)ret=ret*x%MOD;
            x=x*x%MOD;
            y>>=1;
        }
        return ret;
    }
    int to[4*N],lim,L;
    ll inv,W[4*N];
    void ntt(ll *a,int len,int k)
    {
        for(int i=0;i<len;i++)
            if(i<to[i])swap(a[i],a[to[i]]);
        for(int i=1;i<len;i<<=1)
        {
            ll w0 = W[i];
            for(int j=0;j<len;j+=(i<<1))
            {
                ll w=1;
                for(int o=0;o<i;o++,w=w*w0%MOD)
                {
                    ll w1 = a[j+o],w2 = a[j+o+i]*w%MOD;
                    a[j+o] = (w1+w2)%MOD;
                    a[j+o+i] = (w1-w2+MOD)%MOD;
                }
            }
        }
        if(k==-1)
        {
            for(int i=1;i<(len>>1);i++)swap(a[i],a[len-i]);
            for(int i=0;i<len;i++)a[i]=a[i]*inv%MOD;
        }
    }
    int n;
    ll f[N],a[4*N],b[4*N],c[4*N];
    void get_B(int dep)
    {
        if(dep==1)
        {
            now.len=1;
            now.s[0]=fastpow(f[0],MOD-2);
            las = now;
            return ;
        }
        int nxt = (dep+1)/2;
        get_B(nxt);
        lim=1,L=0;
        while(lim<2*dep)lim<<=1,L++;
        for(int i=1;i<lim;i++)to[i]=((to[i>>1]>>1)|((i&1)<<(L-1)));
        inv = fastpow(lim,MOD-2);
        for(int i=1;i<lim;i<<=1)W[i]=fastpow(3,(MOD-1)/(i<<1));
        for(int i=0;i<lim;i++)a[i]=b[i]=0;
        for(int i=0;i<dep;i++)a[i]=f[i];
        for(int i=0;i<nxt;i++)b[i]=las.s[i];
        ntt(a,lim,1),ntt(b,lim,1);
        for(int i=0;i<lim;i++)c[i]=a[i]*b[i]%MOD*b[i]%MOD;
        ntt(c,lim,-1);
        now.len=dep;
        for(int i=0;i<dep;i++)now.s[i]=(2*las.s[i]-c[i]+MOD)%MOD;
        las = now;
    }
    int main()
    {
        read(n);
        for(int i=0;i<n;i++)read(f[i]);
        get_B(n);
        now.print(n);
        return 0;
    }
  • 相关阅读:
    cocos2d-x 纹理研究
    cocos2d-x 获取图片的某像素点的RGBA颜色
    cocos2d-x Menu、MenuItem
    cocos2d-x ScrollView、TableView
    cocos2d-x RenderTexture
    cocos2d-x NotificationCenter
    cocos2d-x ClippingNode
    cocos2d-x Animation
    JDK,JRE,JVM区别与联系(ZZ)
    SQL中join的用法
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10351698.html
Copyright © 2011-2022 走看看