2179: FFT快速傅立叶

来源:互联网 发布:grub4dos 引导linux 编辑:程序博客网 时间:2024/06/02 03:31

2179: FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 2803  Solved: 1431
[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

[Submit][Status][Discuss]



上一个快速数论变换,在FFT基础上稍作修改就行

模数取1004535809,原根是3

#include<iostream>  #include<cstdio>  #include<cmath>  #include<algorithm>  #include<cstring>  using namespace std;    const int maxn = 2E5 + 10;  typedef long long LL;  const LL mo = 1004535809;    LL g[maxn],A[maxn],B[maxn],C[maxn],D[maxn];  int n,N,L,rev[maxn],Num[maxn];  char ch[maxn];    LL ksm(LL x,LL y){LL ret = 1;for (; y; y >>= 1LL) {if (y&1LL) ret = ret*x%mo;x = x*x%mo;}return ret;}  void NTT(LL *a,int on){for (int i = 0; i < N; i++)D[i] = a[rev[i]];for (int i = 0; i < N; i++) a[i] = D[i];for (int k = 2; k <= N; k <<= 1) for (int i = 0; i < N; i += k) {int w = 0;for (int j = i; j < i + (k>>1); j++) {LL u = a[j];LL t = g[w]*a[j+(k>>1)]%mo;a[j] = (u + t)%mo;a[j+(k>>1)] = (u - t + mo)%mo;w += (N/k);}}if (on == -1) {LL inv = ksm(N,mo-2);for (int i = 0; i < N; i++)a[i] = a[i]*inv%mo;}}  int main()  {      #ifdef DMC          freopen("DMC.txt","r",stdin);      #endif            cin >> n;      for (N = 1; N <= n; N <<= 1,++L);       N <<= 1; ++L;      for (int i = 0; i < N; i++) {          int len = 0;          for (int x = i; x; x >>= 1) Num[len++] = x&1;          for (int j = 0; j < L; j++)              rev[i] <<= 1,rev[i] |= Num[j];      }      scanf("%s",ch);      for (int i = 0; i < n; i++)           A[i] = ch[n - i - 1] - '0';      scanf("%s",ch);      for (int i = 0; i < n; i++)          B[i] = ch[n - i - 1] - '0';            g[0] = g[N] = 1;      g[1] = ksm(3,(mo - 1)/(1LL*N));      for (int i = 2; i < N; i++)          g[i] = g[i-1]*g[1]%mo;      NTT(A,1); NTT(B,1);      for (int i = 0; i < N; i++)          C[i] = A[i]*B[i]%mo;      for (int i = 0; i < N/2; i++)          swap(g[i],g[N - i]);      NTT(C,-1);      for (int i = 0; i < N; i++) {          C[i + 1] += C[i]/10LL;          C[i] %= 10LL;      }      int pos;      for (int i = N - 1; i >= 0; i--)          if (C[i]) {pos = i; break;}      for (int i = pos; i >= 0; i--)          printf("%d",C[i]);      return 0;  }  

0 0
原创粉丝点击