【模板】A*B Problem(FFT快速傅里叶)
题目:给出两个n位10进制整数x和y,你需要计算x*y。($n \leq 60000$)
分析:
两个正整数的相乘可以视为两个多项式的相乘,
例如 $15 \times 16 = 240$,
可写成 $(5+x)*(6+x) = 30 + 11x + x^2$,$x=10$
这样得到多项式 $A(x)$ 和 $B(x)$,并且能用FFT求出 $C(x)=A(x)B(x)$,
怎么得到最终结果,我们要将 $x=10$ 代入吗?
$n$ 这么大,遍历一遍也没有这么大的数据类型能存下,其次,这也不是必要的。
$x=10$ 是 $C(x)$ 已经相当于十进制,我们模拟一下进位就可以了。
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN = * + ;
inline int read() {
char c = getchar(); int x = , f = ;
while (c < '' || c > '') {if (c == '-')f = -; c = getchar();}
while (c >= '' && c <= '') {x = x * + c - ''; c = getchar();}
return x * f;
}
const double Pi = acos(-1.0);
const double Eps = 1e-;
double ccos[MAXN], ssin[MAXN];
struct complex {
double x, y;
complex (double xx = , double yy = ) {x = xx, y = yy;}
} a[MAXN], b[MAXN];
complex operator + (complex a, complex b) { return complex(a.x + b.x , a.y + b.y);}
complex operator - (complex a, complex b) { return complex(a.x - b.x , a.y - b.y);}
complex operator * (complex a, complex b) { return complex(a.x * b.x - a.y * b.y , a.x * b.y + a.y * b.x);} //不懂的看复数的运算那部分
void fast_fast_tle(int limit, complex *a, int type) {
if (limit == ) return ; //只有一个常数项
complex a1[limit >> ], a2[limit >> ];
for (int i = ; i < limit; i += ) //根据下标的奇偶性分类
a1[i >> ] = a[i], a2[i >> ] = a[i + ];
fast_fast_tle(limit >> , a1, type);
fast_fast_tle(limit >> , a2, type);
complex Wn = complex(ccos[limit] , type * ssin[limit]), w = complex(, );
//complex Wn = complex(cos(2.0 * Pi / limit) , type * sin(2.0 * Pi / limit)), w = complex(1, 0);
//Wn为单位根,w表示幂
for (int i = ; i < (limit >> ); i++, w = w * Wn) //这里的w相当于公式中的k
{
complex tmp = w * a2[i];
a[i] = a1[i] + tmp;
a[i + (limit >> )] = a1[i] - tmp; //利用单位根的性质,O(1)得到另一部分
}
} char s[MAXN];
int res[MAXN]; int main() {
int N = read();
scanf("%s", s);
for (int i = ; i < N; i++) a[i].x = s[N--i]-'';
scanf("%s", s);
for (int i = ; i < N; i++) b[i].x = s[N--i]-''; //for(int i = 0;i < N;i++) printf("%f ", a[i]); int limit = ; while (limit <= *N) limit <<= ; for(int i = ;i <= limit;i++)
{
ccos[i] = cos(2.0 * Pi / i);
ssin[i] = sin(2.0 * Pi / i);
} fast_fast_tle(limit, a, );
fast_fast_tle(limit, b, );
//后面的1表示要进行的变换是什么类型
//1表示从系数变为点值
//-1表示从点值变为系数
//至于为什么这样是对的,可以参考一下c向量的推导过程,
for (int i = ; i <= limit; i++)
a[i] = a[i] * b[i];
fast_fast_tle(limit, a, -); for(int i = ;i <= *N;i++) res[i] = int(a[i].x/limit+0.5); int tmp = ; //进位
for(int i = ;i <= *N;i++)
{
res[i] += tmp;
tmp = res[i] / ;
res[i] = res[i] % ;
} bool flag = false;
for (int i = *N; i >= ; i--)
{
if(res[i]) flag = true; //注意处理前导0,题干有说
if(flag) printf("%d", res[i]); //按照我们推倒的公式,这里还要除以n
}
return ;
}
【模板】A*B Problem(FFT快速傅里叶)的更多相关文章
- FFT快速傅里叶模板
FFT快速傅里叶模板…… /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < ...
- [Luogu 1919]【模板】A*B Problem升级版(FFT快速傅里叶)
Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出 ...
- luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
模板 嗯 做多项式乘法,进位 没了 #include<cmath> #include<cstdio> #include<cstring> #include<a ...
- Luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶_FFT
这其实就是一道裸的FFT 核心思想:把两个数拆成两个多项式用FFT相乘,再反序输出 py解法如下: input() print(int(input())*int(input())) 皮一下hihi f ...
- 洛谷 P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
题目来源 吐槽下P3803都是紫题... 真心好写,本想一遍过的...但是 我真是太菜了... #include<bits/stdc++.h> using namespace std; ; ...
- P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. 输出格式: 输出一 ...
- 洛谷P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. 输出格式: 输出一 ...
- 【模板】A*B Problem升级版(FFT快速傅里叶)
题目描述 给出两个 $n$ 位10进制数x和y,求x*y(详见 洛谷P1919) 分析 假设已经学会了FFT/NTT. 高精度乘法只是多项式乘法的特殊情况,相当于$x=10$ 时. 例如n=3,求12 ...
- 洛谷.1919.[模板]A*B Problem升级版(FFT)
题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 ...
随机推荐
- .whl文件安装cuda10.0版本的pytorch1.3.0+torchvision0.4.1
$ python3 -m venv env3$ source env3/bin/activate$ cd env3/share/python-wheels 在此找到对应的版本:https://down ...
- Spring security oauth2 password flow
Spring security oauth2 包含以下两个endpoint来实现Authorization Server: AuthorizationEndpoint: 授权请求访问端点, 默认url ...
- Fineui 实现点击左边树状主菜单链接 打开新窗口或打开多个同一个tab
原文:http://fineui.com/bbs/forum.php?mod=viewthread&tid=7019&page=1#pid31469 代码如下: < ...
- SQL Server 特殊字符及中文汉字的处理
简介 在SQL Server 中很多时候需要对一些字段中特殊的字符做处理,比如某个字段中包含一些回车.制表.换行等特殊字符(这些字符往往来源于Excel).这些特殊字符的存在可能导致无法提取到所需数据 ...
- [Docker] Windows 宿主环境下,共享或上传文件到容器的方法
需求如题. 解决方案1 - 挂载目录(适用于创建新的容器) 格式-v 容器目录 或 -v 本地目录:容器目录 范例Linux宿主环境下:使用镜像 nginx:latest,以后台模式启动一个容器,将容 ...
- java中通过Adb判断PC是否连接了移动设备
最近用到PC端和移动端通过USB连接传输数据的方式,于是总在使用Adb命令,为了逻辑的严谨和代码容错,想在传输数据的之前,PC和移动端先建立一次会话,防止移动端还未连接就直接传输数据会报错,找了很久并 ...
- JS中,JSON 和 对象互转,数组和字符串的转换?
JSON 与 J对象转化 要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法: 如下: var json = JSON.stringify({a: 'Hello', b ...
- count_if 功能模板
count_if 功能模板 template <class InputIterator, class UnaryPredicate> typename iterator_traits< ...
- PHP 使用 pdo 操作oracle数据库 报错
## SELECT UNID,NAME,NAME_XML WHERE UNID>=10 AND UNID<=15 ## 在10到15这5条数据中不为空数据php: symbol looku ...
- eclipse创建springboot项目的三种方法
本文链接:https://blog.csdn.net/mousede/article/details/81285693 方法一 安装STS插件 安装插件导向窗口完成后,在eclipse右下角将会出现安 ...