• 模板 NTT 快速数论变换


    NTT裸模板,没什么好解释的

    这种高深算法其实也没那么必要知道原理

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define N (1<<17)+10
     5 #define ll long long 
     6 using namespace std;
     7 
     8 ll inv3,invl;
     9 int r[N];
    10 ll A[N],B[N],C[N],mulwn[N],invwn[N];
    11 char s1[N],s2[N];
    12 const ll p=998244353;
    13 ll qpow(ll x,ll y,ll mo){
    14     ll ans=1;
    15     while(y){
    16         if(y&1) ans=(ans*x)%mo;
    17         x=(x*x)%mo,y>>=1;
    18     }return ans;
    19 }
    20 void pre(int len,int l)
    21 {
    22     inv3=qpow(3,p-2,p),invl=qpow(len,p-2,p);
    23     for(int i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    24     for(ll i=1;i<=len;i<<=1) mulwn[i]=qpow(3,(p-1)/i,p);
    25     for(ll i=1;i<=len;i<<=1) invwn[i]=qpow(mulwn[i],p-2,p);
    26 }
    27 void NTT(ll *a,int len,int type)
    28 {
    29     for(int i=0;i<len;i++)
    30         if(i<r[i]) swap(a[i],a[r[i]]);
    31     for(int k=2;k<=len;k<<=1)
    32     {
    33         ll wn=(type>0)?mulwn[k]:invwn[k];
    34         int mid=k>>1;
    35         for(int i=0;i<len;i+=k)
    36         {
    37             ll w=1;
    38             for(int j=0;j<mid;j++,w=(w*wn)%p)
    39             {
    40                 ll t=(w*a[i+j+mid])%p;
    41                 a[i+j+mid]=(a[i+j]-t+p)%p;
    42                 a[i+j]=(a[i+j]+t)%p;
    43             }
    44         }
    45     }
    46     if(type==-1)
    47         for(int i=0;i<len;i++)
    48             a[i]=(a[i]*invl)%p;
    49 }
    50 void NTT_main(ll *a,ll *b,ll *c,int len,int l)
    51 {
    52     NTT(a,len,1);NTT(b,len,1);
    53     for(int i=0;i<len;i++) c[i]=(a[i]*b[i])%p;
    54     NTT(c,len,-1);
    55 }
    56 
    57 int main()
    58 {
    59     int n,len=1,l=0;scanf("%d",&n);
    60     scanf("%s",s1),scanf("%s",s2);
    61     for(int i=0;i<n;i++) A[n-i-1]=s1[i]-'0';
    62     for(int i=0;i<n;i++) B[n-i-1]=s2[i]-'0';
    63     while(len<n+n) len<<=1,l++;
    64     pre(len,l);
    65     NTT_main(A,B,C,len,l);
    66     for(int i=0;i<len;i++)
    67         if(C[i]>9) C[i+1]+=C[i]/10,C[i]%=10;
    68     int j=len;
    69     while(C[j]==0) j--;
    70     while(j>-1) printf("%lld",C[j]),j--;
    71     puts("");
    72     return 0;
    73 }
    74 
    75 
    76  
  • 相关阅读:
    初学Java——数组
    Ubuntu下将软件添加到快捷启动栏的问题
    初学Java——方法
    初学Java——选择
    初学Java——常用类之Math笔记
    初学Java——基本程序设计笔记(2)
    初学Java——基本程序设计笔记(1)
    关于IE浏览器里修改元素style属性的问题
    2.22,2.24工作进度
    2.21工作进度
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697111.html
Copyright © 2020-2023  润新知