bzoj 2179 FFT快速傅立叶(NTT)

2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 3468 Solved: 1820
[Submit][Status][Discuss]
Description

给出两个n位10进制整数x和y,你需要计算x*y。

Input

第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

Output

输出一行,即x*y的结果。

Sample Input

1

3

4

Sample Output

12

数据范围:

n<=60000


【分析】

NTT解法



【代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mod=479*(1<<21)+1; 
const int mxn=400005;
char s[mxn];
int n,m,L;
int a[mxn],b[mxn],R[mxn];
inline int ksm(int a,int k)
{
    int res=1;
    while(k)
    {
        if(k&1) res=((ll)res*a)%mod; 
        a=((ll)a*a)%mod;
        k>>=1;
    }
    return res; 
}
inline void NTT(int *a,int f)
{
    int i,j,k;
    fo(i,0,n-1) if(i<R[i]) swap(a[i],a[R[i]]);
    for(i=1;i<n;i<<=1)
    {
        int wn=ksm(3,(mod-1)/(i<<1));
        for(j=0;j<n;j+=(i<<1))
        {
            int w=1;
            for(k=0;k<i;k++,w=((ll)w*wn)%mod)
            {
                int x=a[j+k],y=((ll)w*a[j+k+i])%mod;
                a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
            }
        }
    }
    if(f==-1)
    {
        reverse(a+1,a+n);
        int rev=ksm(n,mod-2);
        fo(i,0,n-1) a[i]=((ll)a[i]*rev)%mod;
    }
}
int main()
{
    int i,j,k;
    scanf("%d",&n);
    n--;
    scanf("%s",s);
    fo(i,0,n) a[i]=s[n-i]-'0';
    scanf("%s",s);
    fo(i,0,n) b[i]=s[n-i]-'0';
    m=2*n;for(n=1;n<=m;n<<=1) L++;
    fo(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<L-1);
    NTT(a,1),NTT(b,1);
    fo(i,0,n) a[i]=((ll)a[i]*b[i]%mod);
    NTT(a,-1);
    fo(i,0,m) if(a[i]>=10)
    {
        a[i+1]+=a[i]/10,a[i]%=10;
        if(i==m) m++;
    }
    while(!a[m]) m--;
    for(i=m;i>=0;i--) printf("%d",a[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值