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

    思路

    多项式求逆就是对于一个多项式(A(x)),求一个多项式(B(x)),使得(A(x)B(x) equiv 1 (mod x^n))

    假设现在多项式只有一项,显然(B(x))的第0项(常数项)就是(A(x))的第0项(常数项)的逆元(所以(A(x))有没有逆元取决于(A(x))的常数项有没有逆元)

    那我们可以利用递归的方法,

    现在要求

    [A(x)B(x) equiv 1 (mod x^n) ]

    假设有多项式(B'(x)),满足

    [A(x)B'(x)equiv 1 (mod x^{lfloorfrac{n}{2} floor}) ]

    则要求的(B(x)),必定也满足

    [A(x)B(x) equiv 1 (mod x^{lfloorfrac{n}{2} floor}) ]

    所以有

    [A(x)(B(x)-B'(x)) equiv 0 (mod x^{lfloorfrac{n}{2} floor})\B(x)-B'(x)equiv 0 (mod x^{lfloorfrac{n}{2} floor})\ (B(x)-B'(x))^2equiv 0 (mod x^{n})\ B^2(x)-2B(x)B'(x)+B'^2(x)equiv 0 (mod x^{n})\ ]

    两侧都乘(A(x))

    [B(x)-2B'(x)+2A(x)B'^2(x)equiv 0 (mod x^n) ]

    所以

    [B(x)equiv B'(x)(2-A(x)B'(x)) ]

    递归求解即可

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    const int MOD = 998244353,G = 3, invG = 332748118;
    int pow(int a,int b){
        int ans=1;
        while(b){
            if(b&1)
                ans=(a*ans)%MOD;
            a=(a*a)%MOD;
            b>>=1;
        }
        return ans;
    }
    void NTT(int *a,int n,int opt){
        int lim=0;
        while((1<<lim)<n)
            lim++;
        n=(1<<lim);
        for(int i=0;i<n;i++){
            int t=0;
            for(int j=0;j<lim;j++)
                if((i>>j)&1)
                    t|=(1<<(lim-j-1));
            if(t<i)
                swap(a[t],a[i]);
        }
        for(int i=2;i<=n;i<<=1){
            int len=i/2;
            int tmp=pow((opt)?G:invG,(MOD-1)/i);
            for(int j=0;j<n;j+=i){
                int mid=1;
                for(int k=j;k<j+len;k++){
                    int t=a[k+len]*mid;
                    a[k+len]=(a[k]-t+MOD)%MOD;
                    a[k]=(a[k]+t)%MOD;
                    mid=(mid*tmp)%MOD;
                }
            }
        }
        if(!opt){
            int invn=pow(n,MOD-2);
            for(int i=0;i<n;i++)
                a[i]=(a[i]*invn)%MOD;
        }
    }
    int c[300100],a[300100],b[300100],n;
    void get_inv(int times,int *a,int *b){
        if(times==1){
            b[0]=pow(a[0],MOD-2);
            return;
        }
        get_inv((times+1)>>1,a,b);
        while((times<<1)>n)
            n<<=1;
        for(int i=0;i<times;i++){
            c[i]=a[i];
        }
        for(int i=times;i<n;i++){
            c[i]=0;
        }
        NTT(c,n,1);
        NTT(b,n,1);
        for(int i=0;i<n;i++){
            b[i]=((2-c[i]*b[i]%MOD)%MOD+MOD)%MOD*b[i]%MOD;
        }
        NTT(b,n,0);
        for(int i=times;i<n;i++){
            b[i]=0;
        }
    }
    signed main(){
        scanf("%lld",&n);
        int tx=n;
        for(int i=0;i<tx;i++)
            scanf("%lld",&a[i]);
        n=1;
        get_inv(tx,a,b);
        for(int i=0;i<tx;i++){
            printf("%lld ",(b[i]+MOD)%MOD);
        }
        return 0;
    }
    
  • 相关阅读:
    生成器
    ELK出现unassigned_shards解决办法
    ElK集群 采集 redis 数据
    postgresql-12编译安装
    openshift 3.11安装部署
    Linux TCP漏洞 CVE-2019-11477 CentOS7 修复方法
    zabbix-server安装部署配置
    zabbix-proxy安装部署
    harbor镜像仓库-02-https访问配置
    harbor镜像仓库-01-搭建部署
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10566972.html
Copyright © 2011-2022 走看看