zoukankan      html  css  js  c++  java
  • [多项式求逆]多项式求逆模板

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <memory.h>
    using namespace std;
    typedef long long ll;
    const int N=524288;
    const ll P=998244353;
    int n,rev[N],mxb,bit;
    ll fake_a[N],fake_b[N],a[N],b[2][N];
    
    void Get_Rev(int bit,int mxb) {for (int i=1;i<mxb;i++)    rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1);}
    
    ll Pow(ll x,ll y) {ll ans=1;for (;y;y>>=1,(x*=x)%=P) (ans*=(y&1?x:1))%=P;return ans;}
    
    void NTT(ll *a,int n,int idft) {
        for (int i=1;i<=n;i++) if (rev[i]>i) swap(a[rev[i]],a[i]);
        for (int mlen=1;mlen<n;mlen<<=1) {
            ll g1=Pow(3,(P-1)/(mlen<<1));
            if (idft<0) g1=Pow(g1,P-2);
            for (int l=0,len=mlen<<1;l<n;l+=len) {
                ll gk=1;
                for (int i=l;i<l+mlen;i++) {
                    ll x=a[i],y=(a[i+mlen]*gk)%P;
                    a[i]=(x+y)%P;a[i+mlen]=(x-y+P)%P;
                    (gk*=g1)%=P;
                }
            }
        }
        if (idft<0) {
            ll inv=Pow(n,P-2);
            for (int i=0;i<n;i++) (a[i]*=inv)%=P;
        }
    }
    
    void Roll_Multi(ll *a,ll *b,int mxb) {
        memset(fake_a,0,sizeof fake_a);
        memset(fake_b,0,sizeof fake_b);
        int half=mxb>>1;
        for (int i=0;i<half;i++) fake_a[i]=a[i],fake_b[i]=b[i];
        NTT(fake_a,mxb,1);NTT(fake_b,mxb,1);
        for (int i=0;i<mxb;i++) (fake_a[i]*=fake_b[i])%P;
        NTT(fake_a,mxb,-1);
        for (int i=0;i<mxb;i++) a[i]=fake_a[i];
    }
    
    void Calc_Inv() {
        
    }
    
    int main() {
        scanf("%d",&n);
        for (int i=0;i<n;i++) scanf("%lld",&a[i]);
        int j=0,bit=1;
        b[j][0]=Pow(a[0],P-2);
        for (int mlen=1,len=2;mlen<(n<<1);mlen<<=1,len<<=1,j^=1,++bit) {
            memset(b[j^1],0,sizeof b[j^1]);Get_Rev(bit,len);
            for (int i=0;i<mlen;i++) b[j^1][i]=(b[j][i]<<1)%P;
            Roll_Multi(b[j],b[j],len);
            Roll_Multi(b[j],a,len);
            for (int i=0;i<mlen;i++) b[j^1][i]=(b[j^1][i]-b[j][i]+P)%P;
        }
        for (int i=0;i<n;i++) printf("%lld ",b[j][i]);
    }
    View Code

    码着,找时间写题解

    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/mastervan/p/11149080.html
Copyright © 2011-2022 走看看