BZOJ 2179 FFT快速傅立叶 题解
2016-07-03 11:06
309 查看
bzoj 2179
Description
给出两个n位10进制整数x和y,你需要计算x*y。
【题目分析】
高精裸题。练手。
【代码】
1、手动高精
FFT
Description
给出两个n位10进制整数x和y,你需要计算x*y。
【题目分析】
高精裸题。练手。
【代码】
1、手动高精
#include<bits/stdc++.h> using namespace std; const double pi=acos(-1.0); int rev[200001],ans[200001],len,n,m; char s[200001]; struct P { double x,y; inline P operator +(P a) {return (P){x+a.x,y+a.y};} inline P operator -(P a) {return (P){x-a.x,y-a.y};} inline P operator *(P a) {return (P){x*a.x-y*a.y,x*a.y+y*a.x};} }a[200001],b[200001],c[200001]; inline void fft(P *x,int n,int flag)//快速傅立叶变换 { for (int i=0;i<n;++i) if (rev[i]>i) swap(x[rev[i]],x[i]); for(int m=2;m<=n;m<<=1) { P wn=(P){cos(2.0*pi/m*flag),sin(2.0*pi/m*flag)}; for(int i=0;i<n;i+=m) { P w=(P){1.0,0};int mid=m>>1; for (int j=0;j<mid;++j) { P u=x[i+j],v=x[i+j+mid]*w; x[i+j]=u+v;x[i+j+mid]=u-v; w=w*wn; } } } } int main() { scanf("%d",&n); scanf("%s",s);for (int i=0;i<n;++i) a[i].x=s[n-i-1]-'0'; scanf("%s",s);for (int i=0;i<n;++i) b[i].x=s[n-i-1]-'0'; m=1;n=n*2-1; while (m<=n) m<<=1,len++; n=m; for (int i=0;i<n;++i) { int t=i,ret=0; for (int j=1;j<=len;++j) ret<<=1,ret|=t&1,t>>=1; rev[i]=ret; } fft(a,n,1);fft(b,n,1);//转过去 for (int i=0;i<n;++i) c[i]=a[i]*b[i];//高效率高精度 fft(c,n,-1);//又回来 for (int i=0;i<n;++i) ans[i]=(c[i].x/n)+0.5;//精度误差 for (int i=0;i<n;++i) ans[i+1]+=ans[i]/10,ans[i]%=10;//进位 n++; while (!ans &&n) n--;//确定第一个数的位置 for (int i=n;i>=0;--i) putchar(ans[i]+'0');//输出 }
FFT
相关文章推荐
- 大数阶乘算法
- C/C++代码跟踪
- 动画篇之帧动画
- c#实现关闭当前窗体并打开另一个已经创建的窗体
- OpenGL绘制几何物体(特性)
- JavaScript闭包
- HDU-5703-Desert【2016CCPC女生专场】
- TSP问题之回溯算法
- 241. Different Ways to Add Parentheses
- scanf正则表达式
- Matlab的GUI参数传递方式总结
- php中pdo的一些用法
- TimesTen 数据库复制学习:16. 一个缓存组,复制,客户端自动切换的串烧实验
- 初次邂逅Hibernate之进一步了解
- Oltu在Jersey框架上实现oauth2.0授权模块
- github 提交报403 forbidden的错误解决
- 70. Climbing Stairs
- 微软开源区块链平台项目 Bletchle
- 大数据:从入门到XX(五)
- csdn待改进点之30------>博客浏览数会变小啊