• 多项式求逆


    多项式求逆

    题意

    给出一个多项式 $ G( x ) $ 求一个多项式 $ F( x ) $ 满足 $ F( x ) * G( x ) = 1 ( mod x^n )$,系数对998244353取模。

    解法

    假设现在我们已经求出了 (G( x )) 在膜 $ x ^ { [ frac {n} {2} ] }$ 下的逆元多项式 $ F'( 那么我们有 ) G * F' = 1 ( mod x ^ { [ frac {n} {2} ] } )$ $ G * F = 1 ( mod x ^ n ) $
    ∴ $ ( F' - F )^2 = 0 ( mod x^n )( 拆开则有: ) F'^2 - 2F'F + F^2 = 0 ( mod x^n ) $
    左右同乘 $ G $ 有:
    $ GF'^2 - 2F' + GF = 0 ( mod x^n ) ( 移项有: ) F = 2F' - GF'^2 ( mod x^n )$
    然后我们就有递推式了。同时我们可以知道,当 $ n = 1$ 时,$ F[0] = inv( G[0] ) $,所以一个多项式有逆元的充要条件为他的常数项有逆元。
    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #define INF 2139062143
    #define MAX 0x7ffffffffffffff
    #define del(a,b) memset(a,b,sizeof(a))
    #define Rint register int
    using namespace std;
    typedef long long ll;
    template<typename T>
    inline void read(T&x)
    {
        x=0;T k=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
    }
    const int maxn=(1e5+5)*3;
    const int mod=998244353;
    const int g=3;
    int mul(int x,int y) {return 1ll*x*y%mod;}
    int add(int x,int y) {return (x+y)%mod;}
    int pul(int x,int y) {return (x-y+mod)%mod;}
    int poww(int a,int b){
        int ans=1;
        while(b){
            if(b&1) ans=mul(ans,a);
            a=mul(a,a);
            b>>=1;
        }
        return ans;
    }
    int inv(int x) {return poww(x,mod-2);}
    void ntt(int n,int f,int *a){
        for(int i=0,j=0;i<n;i++){
            if(i<j) swap(a[i],a[j]);
            for(int l=n>>1;(j^=l)<l;l>>=1);
        }
        for(int i=1;i<n;i<<=1){
            int gn=poww(g,(mod-1)/(i<<1));
            if(f==-1) gn=inv(gn);
            for(int j=0;j<n;j+=(i<<1)){
                int g=1;
                for(int k=0;k<i;k++,g=mul(g,gn)){
                    int x=a[j+k],y=mul(g,a[i+j+k]);
                    a[j+k]=add(x,y);
                    a[i+j+k]=pul(x,y);
                }
            }
        }
        if(f==-1){
            int ni=inv(n);
            for(int i=0;i<n;i++) a[i]=mul(a[i],ni);
        }
    }
    void inv_p(int deg,int *a,int *b,int *temp){
        if(deg==1){
            b[0]=inv(a[0]);
            return;
        }
        inv_p((deg+1)>>1,a,b,temp);
        int p=1;
        for(;p<=deg*2;p<<=1);
        for(int i=0;i<deg;i++) temp[i]=a[i];
        fill(temp+deg,temp+p,0);
        ntt(p,1,temp);ntt(p,1,b);
        for(int i=0;i<p;i++) b[i]=pul( mul( 2 , b[i] ) , mul( b[i] , mul( b[i] , temp[i] )) );
        ntt(p,-1,b);
        fill(b+deg,b+p,0);
    }
    int a[maxn],b[maxn],c[maxn];
    int main()
    {
        int n;
        read(n);
        for(int i=0;i<n;i++) read(a[i]);
        inv_p(n,a,b,c);
        for(int i=0;i<n;i++) printf("%d ",b[i]);
        return 0;
    }
    
  • 相关阅读:
    洛谷P4206 [NOI2005]聪聪与可可(期望dp+最短路)
    bzoj2064: 分裂(状压dp)
    Centos7搭建ansible运维自动化工具
    Centos7自动式脚本搭建jumpserver
    TSP问题—Hopfield神经网络算法
    TSP问题—近似算法
    狭义相对论的数学推导
    线性规划实战—投资的收益和风险
    线性规划的算法分析
    一阶非齐次线性微分方程的算法
  • 原文地址:https://www.cnblogs.com/mrasd/p/9508436.html
Copyright © 2020-2023  润新知