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;
    }
  • 相关阅读:
    系统开机自动运行程序和自动启动服务
    Show/hide mouse cursor
    Trap mouse events outside of my application
    Delphi防止同时出现多个应用程序实例CreateMutex
    用Delphi实现抓屏
    .NET四种注释规范
    再谈C#里4个访问权限修饰符
    什么是组件以及为什么使用组件
    做项目的时候千万不能懒!
    范式篇之一范式理论
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8470402.html
Copyright © 2011-2022 走看看