zoukankan      html  css  js  c++  java
  • NTT模板

    如题(大数乘法)。把FFT种的n次单位根换成模意义下的“n次单位原根”,即$G^{frac{p-1}{n}}$即可。

    //#include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    //#include<math.h>
    //#include<time.h>
    //#include<complex>
    #include<algorithm>
    using namespace std;
    
    int n,m,wei;
    #define maxn 262222
    const int mod=998244353,G=3;
    int a[maxn],b[maxn],c[maxn],rev[maxn];
    
    int powmod(int a,int b)
    {
        int ans=1;
        while (b)
        {
            if (b&1) ans=1ll*ans*a%mod;
            a=1ll*a*a%mod;
            b>>=1;
        }
        return ans;
    }
    
    void dft(int *a,int n,int type)
    {
        for (int i=0;i<n;i++) if (i<rev[i]) {int t=a[i]; a[i]=a[rev[i]]; a[rev[i]]=t;}
        for (int i=1;i<n;i<<=1)
        {
            int w=powmod(G,(mod-1)/(i*2));
            if (type==-1) w=powmod(w,mod-2);
            for (int j=0,p=i<<1;j<n;j+=p)
            {
                int t=1;
                for (int k=0;k<i;k++,t=1ll*t*w%mod)
                {
                    int tmp=a[j+k+i]*1ll*t%mod;
                    a[j+k+i]=(a[j+k]-tmp+mod)%mod;
                    a[j+k]=(a[j+k]+tmp)%mod;
                }
            }
        }
    }
    
    void ntt(int *a,int *b,int *c)
    {
        if (!rev[1]) for (int i=0;i<n;i++)
        {
            rev[i]=0;
            for (int j=0;j<wei;j++) rev[i]|=((i>>j)&1)<<(wei-j-1);
        }
    //    for (int i=0;i<n;i++) cout<<rev[i]<<' ';cout<<endl;
        dft(a,n,1); dft(b,n,1);
        for (int i=0;i<n;i++) c[i]=1ll*a[i]*b[i]%mod;
        dft(c,n,-1);
        int inv=powmod(n,mod-2);
        for (int i=0;i<n;i++) c[i]=1ll*inv*c[i]%mod;
    }
    
    char sa[maxn],sb[maxn];
    int main()
    {
        scanf("%s%s",sa,sb); n=strlen(sa)-1; m=strlen(sb)-1;
        for (int i=0;i<=n;i++) a[i]=sa[n-i]-'0';
        for (int i=0;i<=m;i++) b[i]=sb[m-i]-'0';
        m=m+n; for (n=1,wei=0;n<=m;n<<=1,wei++);
        ntt(a,b,c);
        for (int i=0;i<=m;i++) c[i+1]+=c[i]/10,c[i]%=10;
        if (c[m+1]) m++;
        for (int i=m;i>=0;i--) printf("%d",c[i]);
        return 0;
    }
  • 相关阅读:
    OpenCV 学习笔记(1-1)opecv3.41及其扩展库在VS2015下配置
    OpenCV 学习笔记(11)像素级别指针操作
    (19) 树莓派发送微信消息
    mybatis+spring配置
    spring Ioc 实践
    运用BufferedWriter把数据写入文件
    【转】跟我一起学Spring 3(4)–深入理解IoC(控制反转)和DI(依赖注入)
    [转]Spring MVC之@RequestMapping 详解
    python错误处理
    python函数
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8470402.html
Copyright © 2011-2022 走看看