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

    题意:求多项式的逆
    题解:多项式最高次项叫度deg,假设我们对于多项式(A(x)*B(x)equiv 1),已知A,求B
    假设度为n-1,(A(x)*B(x)equiv 1(mod x^{lceil frac{n}{2} ceil})),(A(x)*B'(x)equiv 1(mod x^{lceil frac{n}{2} ceil}))
    两式相减得(B(x)-B'(x)equiv 0(mod x^{lceil frac{n}{2} ceil})),平方得(B(x)^2-2*B(x)*B'(x)+B'(x)^2equiv 0(mod x^n))
    注意到mod数也平方了,这是因为如果(A(x)equiv 0(modx^n)),就说明A的0-n-1项都是0,对于n到2*n-1项第x项来说有(sum_{i=1}^x A(i)*A(x-i)),一定有一项小于n,则必为0
    对于上式,两边同乘A(x),则有(B(x)=2*B'(x)-A(x)*B'(x))
    可以递推解决

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 998244353
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    //#define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    template<typename T>
    inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>
    inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const double eps=1e-8;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=400000+10,inf=0x3f3f3f3f;
    
    ll a[N<<3],b[N<<3],c[N<<3];
    int rev[N<<3];
    void getrev(int bit)
    {
        for(int i=0;i<(1<<bit);i++)
            rev[i]=(rev[i>>1]>>1) | ((i&1)<<(bit-1));
    }
    void ntt(ll *a,int n,int dft)
    {
        for(int i=0;i<n;i++)
            if(i<rev[i])
                swap(a[i],a[rev[i]]);
        for(int step=1;step<n;step<<=1)
        {
            ll wn=qp(3,(mod-1)/(step*2));
            if(dft==-1)wn=qp(wn,mod-2);
            for(int j=0;j<n;j+=step<<1)
            {
                ll wnk=1;
                for(int k=j;k<j+step;k++)
                {
                    ll x=a[k];
                    ll y=wnk*a[k+step]%mod;
                    a[k]=(x+y)%mod;a[k+step]=(x-y+mod)%mod;
                    wnk=wnk*wn%mod;
                }
            }
        }
        if(dft==-1)
        {
            ll inv=qp(n,mod-2);
            for(int i=0;i<n;i++)a[i]=a[i]*inv%mod;
        }
    }
    void pol_inv(int deg,ll *a,ll *b)
    {
        if(deg==1){b[0]=qp(a[0],mod-2);return ;}
        pol_inv((deg+1)>>1,a,b);
        int sz=0;while((1<<sz)<=deg)sz++;sz++;
        getrev(sz);int len=1<<sz;
        for(int i=0;i<deg;i++)c[i]=a[i];
        for(int i=deg;i<len;i++)c[i]=0;
        ntt(c,len,1),ntt(b,len,1);
        for(int i=0;i<len;i++)
            b[i]=(2ll-c[i]*b[i]%mod+mod)%mod*b[i]%mod;
        ntt(b,len,-1);
        for(int i=deg;i<len;i++)b[i]=0;
    }
    int main()
    {
        int n;scanf("%d",&n);
        for(int i=0;i<n;i++)scanf("%lld",&a[i]);
        pol_inv(n,a,b);
        for(int i=0;i<n;i++)printf("%lld ",b[i]);puts("");
        return 0;
    }
    /********************
    
    ********************/
    
  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9525106.html
Copyright © 2011-2022 走看看