[Luogu 1919]【模板】A*B Problem升级版(FFT快速傅里叶)

Description

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

Input

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

Output

输出一行,即x*y的结果。(注意判断前导0)

Sample Input

1
3
4

Sample Output

12

HINT

n<=60000

题解

A*B Problem。和 A+B Problem 一样简单。

1 input() and print(int(input()) * int(input()))

对于一个大数 $\overline{a_na_{n-1}\cdots a_0}$ ,显然我们可以将其记为 $N=a_0\cdot 10^0+a_1\cdot 10^1+\cdots+a_n\cdot10^n$ 。将 $10^k$ 变为形式幂级数 $x^k$ : $N=a_0\cdot x^0+a_1\cdot x^1+\cdots+a_n\cdot x^n$ 。显然这是一个多项式。? $FFT$ 的板子即可。

注意输入的数有前导零...

 1 //It is made by Awson on 2018.1.27
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12 #include <cstring>
13 #include <complex>
14 #include <iostream>
15 #include <algorithm>
16 #define LL long long
17 #define dob complex<double>
18 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
19 #define Max(a, b) ((a) > (b) ? (a) : (b))
20 #define Min(a, b) ((a) < (b) ? (a) : (b))
21 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
22 #define writeln(x) (write(x), putchar(‘\n‘))
23 #define lowbit(x) ((x)&(-(x)))
24 using namespace std;
25 const int INF = ~0u>>1;
26 const double pi = acos(-1.0);
27 const int N = 6e4*4;
28 void read(int &x) {
29     char ch; bool flag = 0;
30     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == ‘-‘)) || 1); ch = getchar());
31     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
32     x *= 1-2*flag;
33 }
34 void write(int x) {
35     if (x > 9) write(x/10);
36     putchar(x%10+48);
37 }
38
39 int n, m, L, R[N+5], sum[N+5];
40 dob a[N+5], b[N+5];
41
42 int getnum() {char ch = getchar(); while (ch < ‘0‘ || ch > ‘9‘) ch = getchar(); return ch-48; }
43 void FFT(dob *A, int o) {
44     for (int i = 0; i < n; i++) if (i > R[i]) swap(A[i], A[R[i]]);
45     for (int i = 1; i < n; i <<= 1) {
46         dob wn(cos(pi/i), sin(pi*o/i)), x, y;
47         for (int j = 0; j < n; j += (i<<1)) {
48             dob w(1, 0);
49             for (int k = 0; k < i; k++, w *= wn) {
50                 x = A[j+k], y = w*A[i+j+k];
51                 A[j+k] = x+y, A[i+j+k] = x-y;
52             }
53         }
54     }
55 }
56 void work() {
57     read(n); n--;
58     for (int i = n; i >= 0; i--) a[i] = getnum();
59     for (int i = n; i >= 0; i--) b[i] = getnum();
60     m = n<<1;
61     for (n = 1; n <= m; n <<= 1) L++;
62     for (int i = 0; i < n; i++) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));
63     FFT(a, 1), FFT(b, 1);
64     for (int i = 0; i < n; i++) a[i] *= b[i];
65     FFT(a, -1);
66     for (int i = 0; i <= m; i++) sum[i] = int(a[i].real()/n+0.5);
67     for (int i = 0; i <= m; i++) sum[i+1] += sum[i]/10, sum[i] %= 10;
68     if (sum[m+1]) m++; while (!sum[m]) m--;
69     for (int i = m; i >= 0; i--) write(sum[i]);
70 }
71 int main() {
72     work();
73     return 0;
74 }

原文地址:https://www.cnblogs.com/NaVi-Awson/p/8367115.html

时间: 2024-08-30 00:34:51

[Luogu 1919]【模板】A*B Problem升级版(FFT快速傅里叶)的相关文章

洛谷.1919.[模板]A乘B Problem升级版(FFT)

题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 //n位*n位最多就只有2n位了 //论putchar的速度..还是快的 #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar

P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

P1919 [模板]A*B Problem升级版(FFT快速傅里叶) 思路还是挺简单的. 输入的2个数 \(a=\overline{a_n a_{n-1} a_{n-2}\cdots a_{0}}\) , \(b=\overline{b_m b_{m-1} b_{m-2}\cdots b_{0}}\) 直接把 \(a_i\) 和 \(b_i\) 看做多项式 A 和 B 的系数,做多项式乘法即可.因为 a ,b 可以看做以 \(a_i,b_i\) 为系数,自变量为10的多项式的值,乘完后的多项式的

FFT快速傅里叶模板

FFT快速傅里叶模板-- /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < 2 * len1 || len < 2 * len2) len <<= 1; 2. for i=0 to len1-1 : x1[i](f(i),0) for i=len1 to len-1 : x1[i](0.0) g(x) is same..... 3. fft(x1,len,1) ff

[luogu P3384] [模板]树链剖分

[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和 操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z 操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和 输入输出格式 输入格式: 第一行包含4个正整数

洛谷P3803 【模板】多项式乘法(FFT)

P3803 [模板]多项式乘法(FFT) 题目背景 这是一道FFT模板题 题目描述 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输入输出格式 输入格式: 第一行2个正整数n,m. 接下来一行n+1个数字,从低到高表示F(x)的系数. 接下来一行m+1个数字,从低到高表示G(x))的系数. 输出格式: 一行n+m+1个数字,从低到高表示F(x)∗G(x)的系数. 输入输出样例 输入样例#1: 复制 1 2 1 2 1 2 1 输出样例#1: 复制 1

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> #include<ctime> #include<queue> #inc

luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

模板 嗯 做多项式乘法,进位 没了 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define pi acos(-1.0) inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9')c = getchar(); while(c <= '9'

luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)|FFT

题目描述 给你两个正整数 a,b,求 a×b. 输入格式 第一行一个正整数,表示 a: 第二行一个正整数,表示 b. 输出格式 输出一行一个整数表示答案. #include<cmath> #include<string> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int _=4e6+10; const double Pi=a

luogu P3803 【模板】多项式乘法(FFT)

题目背景 这是一道 FFT 模板题 题目描述 给定一个 n 次多项式 F(x),和一个 m 次多项式 G(x). 请求出 F(x) 和 G(x) 的卷积. 输入格式 第一行 2 个正整数 n,m. 接下来一行 n+1 个数字,从低到高表示 F(x) 的系数. 接下来一行 m+1 个数字,从低到高表示 G(x) 的系数. 输出格式 一行 n+m+1 个数字,从低到高表示 F(x)*G(x) 的系数. #include<cmath> #include<cstdio> #include&