您的位置:首页 > 其它

[bzoj2179][快速傅里叶][ntt]FFT快速傅立叶

2018-03-03 20:50 357 查看
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
,rev
,a[1000000],b
;
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--]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: