复数fft的时间复杂度_FFT && 复数重载

复数重载 与 FFT

1.复数重载:

重载了复数的运算,即重载了复数的加减乘以及赋初值。

struct Complex{ //复数的重载

double r,i;

IL Complex(){r = 0; i = 0;}

IL Complex(RG double a,RG double b){r = a; i = b;}

IL Complex operator +(Complex B){ return Complex(r+B.r,i+B.i); }

IL Complex operator -(Complex B){ return Complex(r-B.r,i-B.i); }

IL Complex operator *(Complex B){

return Complex(r*B.r-i*B.i , r*B.i+i*B.r);

}

};

其中\(f.r\)为实部 ,\(f.i\)为虚部。

2.FFT算法:

计算多项式\(f_1\)*\(f_2\) == \(f_3\)的算法,

时间复杂度\(O(n\ logn)\) , 空间最好开\(O(3n)\)到\(O(4n)\)左右;

Complex f1[_],f2[_],X,Y; int f3[_]; //f3储存卷积的系数.

const double PI = acos(-1);

IL void Init(){ //读入数据,预处理.

cin >> n >> m;

for(RG int i = 0; i <= n; i ++)cin >> f1[i].r;

for(RG int j = 0; j <= m; j ++)cin >> f2[j].r; //读入两个多项式

m += n; l = 0;

for(n = 1; n <= m; n<<=1)l++;

//此时m保存卷积的长度,n等于二进制补全后 数列长度+1 .

//Rader预处理:

for(RG int i = 0; i < n; i ++)R[i] = (R[i>>1]>>1) | ((i&1)<

}

IL void FFT(Complex *P , int opt){

for(RG int i = 0; i < n; i ++)

if(i < R[i]) swap(P[i] , P[R[i]]); //Rader 排序

for(RG int i = 1; i < n; i<<=1){

Complex W(cos(PI/i),opt*sin(PI/i));

for(RG int p = i<<1 , j = 0; j < n; j += p){

Complex w(1,0);

for(RG int k = 0; k < i; k ++,w = w*W){

X = P[j + k] , Y = w*P[j + k + i];

P[j + k] = X + Y; P[j + k + i] = X - Y;

}

}

}

if(opt == -1) for(RG int i = 0; i < n; i ++)P[i].r /= n;

}

int main(){

Init();

//计算f1*f2

FFT(f1,1); FFT(f2,1);

for(RG int i = 0; i <= n; i ++)f1[i] = f1[i]*f2[i];

FFT(f1,-1);

//最后结果存在f1中.

for(RG int i = 0; i <= m; i ++)f3[i] = (int)(f1[i].r+0.5));

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值