当前位置:网站首页>FFT模板
FFT模板
2022-08-10 07:56:00 【ThXe】
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int N = 5000007;
const double PI = acos(-1);
inline int read()
{
register int x = 0, f = 1;
register char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
struct Complex
{
double x, y;
Complex(double x = 0, double y = 0) : x(x), y(y) {
}
}a[N], b[N];
Complex operator * (Complex J, Complex Q) {
//模长相乘,幅度相加
return Complex(J.x * Q.x - J.y * Q.y, J.x * Q.y + J.y * Q.x);
}
Complex operator - (Complex J, Complex Q) {
return Complex(J.x - Q.x, J.y - Q.y);
}
Complex operator + (Complex J, Complex Q) {
return Complex(J.x + Q.x, J.y + Q.y);
}
struct fft {
int n, m;int res, ans[N];
int limit = 1;
int L;//二进制的位数
int R[N];
void FFT(Complex* A, int type)
{
for (int i = 0; i < limit; ++i)
if (i < R[i])
swap(A[i], A[R[i]]);
//i小于R[i]时才交换,防止同一个元素交换两次,回到它原来的位置。
//从底层往上合并
for (int mid = 1; mid < limit; mid <<= 1) {
//待合并区间长度的一半,最开始是两个长度为1的序列合并,mid = 1;
Complex wn(cos(PI / mid), type * sin(PI / mid));//单位根w_n^1;
for (int len = mid << 1, pos = 0; pos < limit; pos += len) {
//len是区间的长度,pos是当前的位置,也就是合并到了哪一位
Complex w(1, 0);//幂,一直乘,得到平方,三次方...
for (int k = 0; k < mid; ++k, w = w * wn) {
//只扫左半部分,蝴蝶变换得到右半部分的答案,w 为 w_n^k
Complex x = A[pos + k];//左半部分
Complex y = w * A[pos + mid + k];//右半部分
A[pos + k] = x + y;//左边加
A[pos + mid + k] = x - y;//右边减
}
}
}
if (type == 1) return;
for (int i = 0; i <= limit; ++i)
A[i].x /= limit;
//最后要除以limit也就是补成了2的整数幂的那个N,将点值转换为系数
//(前面推过了点值与系数之间相除是N)
}
void init()
{
n = read(), m = read();
//读入多项式的每一项,保存在复数的实部
for (int i = 0; i <= n; ++i)
a[i].x = read();
for (int i = 0; i <= m; ++i)
b[i].x = read();
while (limit <= n + m)
limit <<= 1, L++;
//也可以写成:limit = 1 << int(log2(n + m) + 1);
// 补成2的整次幂,也就是N
for (int i = 0; i < limit; ++i)
R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
}
void output()
{
FFT(a, 1);//FFT 把a的系数表示转化为点值表示
FFT(b, 1);//FFT 把b的系数表示转化为点值表示
//计算两个系数表示法的多项式相乘后的点值表示
for (int i = 0; i <= limit; ++i)
a[i] = a[i] * b[i];
//对应项相乘,O(n)得到点值表示的多项式的解C,利用逆变换完成插值得到答案C的点值表示
FFT(a, -1);
for (int i = 0; i <= n + m; ++i)
//这里的 x 和 y 是 double 的 hhh
printf("%d ", (int)(a[i].x + 0.5));//注意要+0.5,否则精度会有问题
}
}FFT;
int main()
{
FFT.init();
FFT.output();
}
边栏推荐
- 人工神经网络模型的特点,人工神经网络模型定义
- Discussion on Chinese Fuzzy Retrieval in Databases
- Power function Exponential function Logarithmic function
- ATH10 sensor reads temperature and humidity
- [深入研究4G/5G/6G专题-56]: L3信令控制-5-无线承载管理
- 神经网络的三种训练方法,神经网络训练全过程
- Rust learning: 6.4_ enumeration of composite types
- CV-人脸识别-2018:ArcFace
- The sixteenth day & the basic operation of charles
- 初使jest 单元测试
猜你喜欢

每日一题,二叉树中增加一行

本地生活商家如何通过短视频赛道,提升销量曝光量?

人工神经网络模型的特点,人工神经网络模型定义

协同工具满足70%-90%的工作需求,成为企业香饽饽

第十六天&charles的基本操作

navicat for mysql 连接时报错:1251-Client does not support authentication protocol requested by server

解决win10win7win8系统找不到指定的模块,注册不了大漠插件的问题

iwemeta元宇宙:阿里首任COO:如何打造销售铁军

阿里巴巴(中国)网络技术有限公司、测试开发笔试二面试题(附答案)

NPU架构与算力分析
随机推荐
The probability distribution and its application
第2章 变量和基本类型读书笔记
SQL SERVER 数据库,表的数据发生增删改,该表的索引会在ldf日志中记录吗?
软件测试面试题避雷(HR面试题)最常见的面试问题和技巧性答复
Bigder:42/100 showCase多少bug可以打回去
详解构建mock服务最方便的神器——Moco
oracle业务表的数据发生增删改,该表的索引会写redo,undo吗?
day16--抓包工具Charles的使用
Is the write performance of raid5 faster than raid10?
iwemeta元宇宙:阿里首任COO:如何打造销售铁军
个人博客系统
winget包管理器
力扣(LeetCode)221. 最大正方形(2022.08.09)
Introduction to the delta method
phpstudy开机自启
CV-人脸识别-2018:ArcFace
WooCommerce installation and rest api usage
添加spark的相关依赖和打包插件(第六弹)
C# 获取PCI等设备的插槽位置信息
day16--The use of the packet capture tool Charles