zoukankan      html  css  js  c++  java
  • Luogu4512 【模板】多项式除法(多项式求逆+NTT)

      http://blog.miskcoo.com/2015/05/polynomial-division 好神啊!

      通过翻转多项式消除余数的影响,主要原理是商只与次数不小于m的项有关。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 550000
    #define P 998244353
    int n,m,t,a[N],b[N],r[N],c[N],d[N],e[N],inv3;
    int ksm(int a,int k)
    {
        if (k==0) return 1;
        int tmp=ksm(a,k>>1);
        if (k&1) return 1ll*tmp*tmp%P*a%P;
        else return 1ll*tmp*tmp%P;
    }
    int inv(int a){return ksm(a,P-2);}
    void DFT(int n,int *a,int p)
    {
        for (int i=0;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
        for (int i=2;i<=n;i<<=1)
        {
            int wn=ksm(p,(P-1)/i);
            for (int j=0;j<n;j+=i)
            {
                int w=1;
                for (int k=j;k<j+(i>>1);k++,w=1ll*w*wn%P)
                {
                    int x=a[k],y=1ll*w*a[k+(i>>1)]%P;
                    a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P;
                }
            }
        }
    }
    void mul(int n,int *a,int *b)
    {
        DFT(n,a,3),DFT(n,b,3);
        for (int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%P;
        DFT(n,a,inv3);
        int invn=inv(n);
        for (int i=0;i<n;i++) a[i]=1ll*a[i]*invn%P;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("division.in","r",stdin);
        freopen("division.out","w",stdout);
        const char LL[]="%I64d";
    #else
        const char LL[]="%lld";
    #endif
        n=read(),m=read();
        for (int i=0;i<=n;i++) a[i]=read();
        for (int i=0;i<=m;i++) b[i]=read();
        reverse(b,b+m+1);
        t=1;c[0]=inv(b[0]);
        inv3=inv(3);
        while (t<n-m+1)
        {
            t<<=1;
            for (int i=0;i<t;i++) d[i]=b[i];
            t<<=1;
            for (int i=0;i<t;i++) r[i]=(r[i>>1]>>1)|(i&1)*(t>>1);
            memcpy(e,c,sizeof(e));
            mul(t,e,d);
            for (int i=0;i<t;i++) e[i]=(P-e[i])%P;
            e[0]=(e[0]+2)%P;
            for (int i=(t>>1);i<t;i++) e[i]=0;
            mul(t,c,e);
            for (int i=(t>>1);i<t;i++) c[i]=0;
            t>>=1;
        }
        memcpy(d,a,sizeof(a));
        reverse(d,d+n+1);
        for (int i=n-m+1;i<=n;i++) c[i]=d[i]=0;
        t=1;while (t<=(n-m+1<<1)) t<<=1;
        for (int i=0;i<t;i++) r[i]=(r[i>>1]>>1)|(i&1)*(t>>1);
        mul(t,c,d);
        for (int i=n-m+1;i<t;i++) c[i]=0;
        reverse(c,c+n-m+1);
        for (int i=0;i<=n-m;i++) printf("%d ",c[i]);cout<<endl;
        reverse(b,b+m+1);
        t=1;while (t<=n) t<<=1;
        for (int i=0;i<t;i++) r[i]=(r[i>>1]>>1)|(i&1)*(t>>1);
        mul(t,c,b);
        for (int i=0;i<m;i++) printf("%d ",(a[i]-c[i]+P)%P);
        return 0;
    }
  • 相关阅读:
    基于接口而非实现编程 和 依赖注入
    程序出错该返回啥?
    js关于for循环实现线程休眠效果的问题
    预祝1024节日快乐!
    20201101_Python的虚拟环境问题
    机器学习——dbscan密度聚类
    公司里使用gitlab管理项目
    MYSQL集群MHA架构实现手册
    vbox导入虚拟电脑网卡MAC问题,MacOS 通过virtualbox安装的centos7虚拟机不能上网解决
    MySQL误操作后如何快速回滚(转)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9437919.html
Copyright © 2011-2022 走看看