spoj VFMUL FFT快速傅立叶变换模板题

  题意;求两个数相乘。

  第一次写非递归的fft,因为一个数组开小了调了两天TAT。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define PI 3.1415926535897932384
#define MAXN 1200000
#pragma optimize("O2")
struct Complex
{
        double x,y;
        Complex(){};
        Complex(double x,double y):x(x),y(y){};
        void init(double x,double y)
        {
                this->x=x;this->y=y;
        }
        Complex operator +(Complex a)
        {
                Complex ret(x + a.x, y + a.y);
                return ret;
        }
        Complex operator -(Complex a)
        {
                Complex ret(x - a.x, y - a.y);
                return ret;
        }
        Complex operator *(Complex a)
        {
                Complex ret(x*a.x - y*a.y, x*a.y + y*a.x);
                return ret;
        }
        Complex operator /(double v)
        {
                Complex ret(x/v,y/v);
                return ret;
        }
        Complex operator =(double x)
        {
                this->x=x;
                return *this;
        }
        void operator -=(Complex a)
        {
                this->x-=a.x;
                this->y-=a.y;
        }
        void operator +=(Complex a)
        {
                this->x+=a.x;
                this->y+=a.y;
        }
};
char ss[MAXN];
int t1[MAXN],t2[MAXN];
int pp[MAXN];
Complex ww[MAXN][2];
Complex g1[MAXN],g2[MAXN];
long long res[MAXN];
int n;
void dft(Complex g[],int len,int sign)
{
        Complex t;
        for (int i=1;i<len;i<<=1)
        {
                for (int j=0;j<len;j+=(i<<1))
                {
                        for (int k=0;k<i;k++)
                        {
                                t=g[j+k];
                                g[j+k]=g[j+k]+g[j+k+i]*ww[k*((n>>1)/i)][sign];
                                g[j+k+i]=t-g[j+k+i]*ww[k*((n>>1)/i)][sign];
                        }
                }
        }
}

int main()
{
        freopen("input.txt","r",stdin);
        //    freopen("output.txt","w",stdout);
        int i,j,k,x,y,z,m;
        int n1,n2;
        int nn;
        scanf("%d",&nn);
        while (nn--)
        {

                scanf("%s",ss);
                m=strlen(ss);
                for (i=0;i<m;i++)
                        t1[(m-i-1)/5]=t1[(m-i-1)/5]*10+ss[i]-‘0‘;
                n1=(m-1)/5+1;
                scanf("%s",ss);
                m=strlen(ss);
                for (i=0;i<m;i++)
                        t2[(m-i-1)/5]=t2[(m-i-1)/5]*10+ss[i]-‘0‘;
                n2=(m-1)/5+1;
                n=max(n1,n2);
                while (n!=(n&(-n)))n-=n&(-n);
                n<<=2;
                for (i=0;i<n;i++)
                        for (j=n>>1,x=1;j;j>>=1,x<<=1)
                                if (i&j)pp[i]+=x;
                for (i=0;i<n1;i++)g1[pp[i]].x=t1[i];
                for (i=0;i<n2;i++)g2[pp[i]].x=t2[i];
                for (i=0;i<=n;i++)
                {
                        ww[i][0].init(cos(2*PI*i/n), -sin(2*PI*i/n));
                        ww[i][1].x=ww[i][0].x;
                        ww[i][1].y=-ww[i][0].y;
                }
                dft(g1,n,0);
                dft(g2,n,0);
                for (i=0;i<n;i++)g2[i]=g1[i]*g2[i];
                for (i=0;i<n;i++)g1[pp[i]]=g2[i];
                dft(g1,n,1);
                for (i=0;i<n;i++)res[i]=(long long)(g1[i].x/n+0.5);
                for (i=0;i<n;i++)res[i+1]+=res[i]/100000,res[i]%=100000;
                m=n;
                while (m && !res[m-1])m--;
                printf("%d",(int)res[m-1]);
                for (i=m-2;i>=0;i--)
                        printf("%05d",(int)res[i]);
                printf("\n");
                memset(t1,0,sizeof(t1[0])*n);
                memset(t2,0,sizeof(t2[0])*n);
                memset(pp,0,sizeof(pp[0])*n);
                memset(res,0,sizeof(res[0])*n);
                memset(g1,0,sizeof(g1[0])*n);
                memset(g2,0,sizeof(g2[0])*n);
        }
}
时间: 2024-11-09 19:06:51

spoj VFMUL FFT快速傅立叶变换模板题的相关文章

FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus

Calculate A * B. Input Each line will contain two integers A and B. Process to end of file. Note: the length of each integer will not exceed 50000. Output For each case, output A * B in one line. Sample Input 1 2 1000 2 Sample Output 2 2000 唉,模板题,膜的邝

UOJ #34 多项式乘法 FFT快速傅立叶变换

题目大意:这是一道模板题. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 using namespace std; const double PI = acos(-1.0); struct Complex{ double x,y; Complex(dou

FFT快速傅立叶变换的工作原理

实数DFT,复数DFT,FFT FFT是计算DFT的快速算法,但是它是基于复数的,所以计算实数DFT的时候需要将其转换为复数的格式,下图展示了实数DFT和虚数DFT的情况,实数DFT将时域中N点信号转换成2个(N/2+1)点的频域信号,其中1个(N/2+1)点的信号称之为实部,另一个(N/2+1)点的信号称之为虚部,实部和虚部分别是正弦和余弦信号的幅度. 相比较而言,复数DFT将2个N点的时域信号转换为2个N点的频域信号.时域和频域中,1个N点信号是实部,另1个N点信号是虚部. 如果要计算N点实

【BZOJ 2179】【FFT模板】 FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1595 Solved: 792 [Submit][Status][Discuss] Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output

快速傅立叶变换(FFT)相关内容汇总

FFT是近年考察非常频繁的算法,与其相关的知识点也相当多样. 这里主要是资料汇总,内容补充和总结等.具体应用应在各大OJ上做相关题目. 目录: 概述 1. 前置技能:数学基础 1.1 多项式概念与运算. 1.2 微积分初步与泰勒展开 1.3 普通型生成函数与指数型生成函数 1.4 线性代数相关(矩阵,行列式与特征多项式) 1.5 组合数与伯努利数 1.6 常系数齐次线性递推 1.7 初等数论与初等代数 1.8 卷积概念与O(n^2)求法 1.9 拉格朗日插值法 2. FFT:快速傅立叶变换算法总

【bzoj2179】FFT快速傅立叶 FFT模板

2016-06-01  09:34:54 很久很久很久以前写的了... 今天又比较了一下效率,貌似手写复数要快很多. 贴一下模板: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #includ

快速傅立叶变换算法FFT——图像处理中的数学原理详解22

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 交流学习可加图像处理研究学习QQ群(529549320) 傅立叶变换以高等数学(微积分)中的傅立叶级数为基

一步一步的无障碍理解快速傅立叶变换

/////////////////////////////////////////////////////////////////////////////////////////////////////// 作者:tt2767 声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 查看本文更新与讨论请点击:http://blog.csdn.net/tt2767 链接被删请百度: CSDN tt2767 ///////////////

GSL 学习笔记(快速傅立叶变换)

GSL 学习笔记(快速傅立叶变换) GNU Scientific Library (GSL)是一个开源的科学计算的函数库,里面实现了大量的数学函数,还提供了方程求解.傅立叶变换等多种功能. GSL 中FFT 的定义如下, 正变换(forward): 逆变换(inverse): 还有一个叫做反向变换: 反变换(backward): 复数FFT,长度为2^N 这是最简单的一种.C89标准中没有定义复数类型,不过gsl 倒是给了个gsl_complex 类型.我们可以使用这个类型,或者直接实部虚部交替