2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 4065 Solved: 2171
[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
HINT
Source
sol:
练ntt的板子
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
const int pyz=998244353;
int g;
int n;
inline int read()
{
char c;
int res,flag=0;
while((c=getchar())>'9'||c<'0') if(c=='-')flag=1;
res=c-'0';
while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0';
return flag?-res:res;
}
const int N=241000;
int nx,lg;
int f[N],rev[N],a[1000000],b[N];
inline int ksm(int s,int t)
{
int res=1;
while(t)
{
if(t&1) res=(ll)res*s%pyz;
s=(ll)s*s%pyz;
t>>=1;
}
return res;
}
inline void Set(int n)
{
nx=1;
while(nx<n) nx<<=1,++lg;
f[0]=1;
g=ksm(3,(pyz-1)/nx);
for(int i=1;i<nx;++i)
{
rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
f[i]=(ll)f[i-1]*g%pyz;
}
}
inline void Dft(int *c,int o)
{
for(int i=0;i<nx;++i)
if(rev[i]>i) swap(c[rev[i]],c[i]);
for(int k=1;k<nx;k<<=1)
{
int len=k<<1;
int wn=o?f[nx/len]:f[nx-nx/len];
for(int s=0;s<nx;s+=len)
{
int w=1;
for(int i=s;i<s+k;i++)
{
int l,r;
l=c[i];
r=(ll)w*c[i+k]%pyz;
c[i]=(l+r)%pyz;
c[i+k]=(l-r+pyz)%pyz;
w=(ll)w*wn%pyz;
}
}
}
}
inline void Mul(int *a,int *b)
{
Dft(a,1);Dft(b,1);
for(int i=0;i<nx;++i) a[i]=(ll)a[i]*b[i]%pyz;
Dft(a,0);
int inv=ksm(nx,pyz-2);
for(int i=0;i<nx;++i) a[i]=(ll)a[i]*inv%pyz;
}
char sr[61000];
int main()
{
// freopen("2179.in","r",stdin);
// freopen(".out","w",stdout);
n=read()-1;
// for(int i=n;i>=0;--i) a[i]=read();
// for(int i=n;i>=0;--i) b[i]=read();
scanf("%s",sr);
for(int i=n;i>=0;--i) a[i]=sr[n-i]-'0';
scanf("%s",sr);
for(int i=n;i>=0;--i) b[i]=sr[n-i]-'0';
Set(n+n+2);
Mul(a,b);
for(int i=0;i<=n+n;++i)
{
a[i+1]+=a[i]/10;
a[i]%=10;
}
int i=n+n;
while(a[i+1])
{
++i;
a[i+1]+=a[i]/10;
a[i]%=10;
}
while(i>=0)
printf("%d",a[i--]);
}