[POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法)

题面

给出两个长度为\(n\)的序列\(B,C\),已知\(A\)和\(B\)的循环卷积为\(C\),求\(A\).

\(n<2^{17}\)

分析

Bluestein算法的模板题,可以参考这篇博客

再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn (1<<17)
const double pi=acos(-1.0);
using namespace std;
struct com{
double real;
double imag;
com(){ }
com(double _real,double _imag){
real=_real;
imag=_imag;
}
com(double x){
real=x;
imag=0;
}
void operator = (const com x){
this->real=x.real;
this->imag=x.imag;
}
void operator = (const double x){
this->real=x;
this->imag=0;
}
friend com operator + (com p,com q){
return com(p.real+q.real,p.imag+q.imag);
}
friend com operator + (com p,double q){
return com(p.real+q,p.imag);
}
void operator += (com q){
*this=*this+q;
}
void operator += (double q){
*this=*this+q;
}
friend com operator - (com p,com q){
return com(p.real-q.real,p.imag-q.imag);
}
friend com operator - (com p,double q){
return com(p.real-q,p.imag);
}
void operator -= (com q){
*this=*this-q;
}
void operator -= (double q){
*this=*this-q;
}
friend com operator * (com p,com q){
return com(p.real*q.real-p.imag*q.imag,p.real*q.imag+p.imag*q.real);
}
friend com operator * (com p,double q){
return com(p.real*q,p.imag*q);
}
void operator *= (com q){
*this=(*this)*q;
}
void operator *= (double q){
*this=(*this)*q;
}
friend com operator / (com p,double q){
return com(p.real/q,p.imag/q);
}
void operator /= (double q){
*this=(*this)/q;
}
friend com operator / (com p,com q){//复数的除法,类似解二元一次方程,代入复数乘法公式解出答案
return com((p.real*q.real+p.imag*q.imag)/(q.real*q.real+q.imag*q.imag),(p.imag*q.real-p.real*q.imag)/(q.real*q.real+q.imag*q.imag));
}
void print(){
printf("%lf + %lf i ",real,imag);
}
}; void fft(com *x,int *rev,int n,int type){
for(int i=0;i<n;i++) if(i<rev[i]) swap(x[i],x[rev[i]]);
for(int len=1;len<n;len*=2){
int sz=len*2;
com wn1=com(cos(2*pi/sz),type*sin(2*pi/sz));
for(int l=0;l<n;l+=sz){
int r=l+len-1;
com wnk=1;
for(int i=l;i<=r;i++){
com tmp=x[i+len];
x[i+len]=x[i]-wnk*tmp;
x[i]=x[i]+wnk*tmp;
wnk=wnk*wn1;
}
}
}
if(type==-1) for(int i=0;i<n;i++) x[i]/=n;
}
void bluestein(com *a,int n,int type){
static com x[maxn*4+5],y[maxn*4+5];
static int rev[maxn*4+5];
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
int N=1,L=0;
while(N<n*4){
L++;
N*=2;
}
for(int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
for(int i=0;i<n;i++) x[i]=com(cos(pi*i*i/n),type*sin(pi*i*i/n))*a[i];
for(int i=0;i<n*2;i++) y[i]=com(cos(pi*(i-n)*(i-n)/n),-type*sin(pi*(i-n)*(i-n)/n));
fft(x,rev,N,1);
fft(y,rev,N,1);
for(int i=0;i<N;i++) x[i]*=y[i];
fft(x,rev,N,-1);
for(int i=0;i<n;i++){
a[i]=x[i+n]*com(cos(pi*i*i/n),type*sin(pi*i*i/n));
if(type==-1) a[i]/=n;//一定记得除以n,因为做一次Bluestein相当于一次FFT,IFFT最后要除n,这里也要除n
}
}
void div(com *a,com *b,com *c,int n){//求解A*B=C
bluestein(b,n,1);
bluestein(c,n,1);
for(int i=0;i<n;i++) a[i]=c[i]/b[i];
bluestein(a,n,-1);
} int n;
com a[maxn+5],b[maxn+5],c[maxn+5];
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lf",&b[i].real);
for(int i=0;i<n;i++) scanf("%lf",&c[i].real);
div(a,b,c,n);
for(int i=0;i<n;i++) printf("%.4f\n",a[i].real);
}

[POJ 2821]TN's Kindom III(任意长度循环卷积的Bluestein算法)的更多相关文章

  1. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  2. 生成任意长度的随机数 JS

    1.Math.random().toString(36).substr(2); 结果:ywv6cnpkliahj4tep0 2.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  3. 求任意长度数组的最大值(整数类型)。利用params参数实现任意长度的改变。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. C语言---递归反向输出任意长度的字符串

    (该字符串可以包含空格和回车!) [题目要求] 编写一个递归函数,实现将输入的任意长度的字符串反向输出的功能. 例如输入字符串:ABCD,输出字符串:DCBA. [题目分析] 应用递归的思想有时可以很 ...

  5. 任意长度的正小数的加法(YT新人之巅峰大决战05)

    Problem Description 话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫"大明". 这时他已经不是那个只会做100以内加法的那个"小明 ...

  6. [c++]大数运算1---利用C++ string实现任意长度正小数、整数之间的加减法

    一.概述 本文属于大大维原创,未经笔者本人允许,严禁转载!!! C/C++中的int类型能表示的范围是-2E31-2E31–1.unsigned类型能表示的范围是0-2E32–1,即 0-429496 ...

  7. [c++]大数运算---利用C++ string实现任意长度正小数、整数之间的加减法

    本文为大大维原创,最早于博客园发表,转载请注明出处!!! 一.概述 C/C++中的int类型能表示的范围是-2E31-2E31–1.unsigned类型能表示的范围是0-2E32–1,即 0-4294 ...

  8. 【模板小程序】任意长度非负十进制数转化为二进制(java实现)

    妈妈再也不用担心十进制数过大了233(注意只支持非负数) import com.google.common.base.Strings; import java.math.BigInteger; imp ...

  9. 串口应用:遵循uart协议发送N位数据(状态优化为3个,适用任意长度的输入数据,取寄存器中的一段(用变量作为边界))

    上一节中成功实现了发送多个字节的数据.把需要发送的数据分成多段遵循uart协议的数据依次发送.上一节是使用状态机实现的,每发一次设定为一个状态,所以需要发送的数据越多,状态的个数越多,代码越长,因而冗 ...

随机推荐

  1. 1. Spring Boot入门

    1.Spring Boot简介 简化Spring应用开发的一个框架 整个Spring技术栈的一个大整合 J2EE开发的一站式解决方案 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 ...

  2. Appium自动化测试之环境安装

    安装前准备: Python 安装包下载       选择想要想在的python包Node-v6.11.2下载安卓SDK下载appium_forwindows下载 以上四个文件下载下来后,分别解压安装, ...

  3. C# Socket TCP发送图片与接收图片

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...

  4. rxjs入门7之其它操作符复习

    一.辅助类操作符 二.过滤数据流 三.转化数据流 四.异常错误处理 五.多播 ,Subject类型

  5. 关于 Promise 的一些简单理解

    一.ES6 中的 Promise 1.JS 如何解决 异步问题? (1)什么是 同步.异步? 同步指的是 需要等待 前一个处理 完成,才会进行 下一个处理. 异步指的是 不需要等待 前一个处理 完成, ...

  6. WPF开源控件扩展库 - MaterialDesignExtensions

    Material Design Extensions 在WPF开源控件库 Material Design in XAML Toolkit(本站介绍:链接)的基础上进行了控件扩展和特性新增.本开源项目中 ...

  7. 使用leveldb

    C++引入leveldb 编译安装: git clone --recurse-submodules https://github.com/google/leveldb.git cd leveldb m ...

  8. 【UER #1】DZY Loves Graph

    UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...

  9. centos8平台基于iftop监控网络流量

    一,iftop的作用: 基于ip统计外部机器与本机之间的网络流量, 可以方便的查看各客户端是否有非正常的到本机的访问 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnbl ...

  10. centos8平台使用ip命令代替ifconfig管理网络

    一,为什么建议使用ip命令代替ifconfig? 1,ifconfig所属的net-tools包已经不再被维护了 虽然可以用,但会发生看不到部分ip等情况, [root@centos8 liuhong ...