【HDU1402】【FFT】A * B Problem Plus

Problem Description

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

Author

DOOM III

Recommend

DOOM III

【分析】

模板,不过我想说的是,这居然是06年的题目。。。太恐怖了。

  1 /*
  2 宋代苏轼
  3 《临江仙·夜饮东坡醒复醉》
  4 夜饮东坡醒复醉,归来仿佛三更。家童鼻息已雷鸣。敲门都不应,倚杖听江声。
  5 长恨此身非我有,何时忘却营营。夜阑风静縠纹平。小舟从此逝,江海寄余生。
  6 */
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <queue>
 12 #include <vector>
 13 #include <iostream>
 14 #include <string>
 15 #include <ctime>
 16 #define LOCAL
 17 const double Pi = acos(-1.0);
 18 const int MAXN = 200000 + 10;
 19 using namespace std;
 20 typedef long long ll;
 21 struct Num {
 22    double a , b;
 23     //构造函数
 24    Num(double x = 0,double y = 0) {a = x; b = y;}
 25     //复数的三种运算
 26    Num operator + (const Num &c) {return Num(a + c.a, b + c.b);}
 27    Num operator - (const Num &c) {return Num(a - c.a, b - c.b);}
 28    Num operator * (const Num &c) {return Num(a * c.a - b * c.b, a * c.b + b * c.a);}
 29 }x1[MAXN] , x2[MAXN];
 30
 31 //注意loglen为log后的长度
 32 void change(Num *t, int len, int loglen){
 33     //蝶形变换后的序列编号
 34     for (int i = 0; i < len; i++){
 35         int x = i, k = 0;
 36         for (int j = 0; j < loglen; j++, x >>= 1) k = (k << 1) | (x & 1);
 37         if (k < i) swap(t[k], t[i]);
 38     }
 39 }
 40 //基2-FFT
 41 void FFT(Num *x, int len, int loglen){
 42     change(x, len, loglen);
 43     int t = 1;
 44     //t为长度
 45     for (int i = 0; i < loglen; i++, (t <<= 1)){
 46         int l = 0, r = l + t;
 47         while (l < len){
 48             //初始化
 49             Num a, b, wo(cos(Pi / t), sin(Pi / t)), wn(1, 0);
 50             for (int j = l; j < l + t; j++){
 51                 a = x[j];
 52                 b = x[j + t] * wn;
 53                 //蝶形计算
 54                 x[j] = a + b;
 55                 x[j + t] = a - b;
 56                 wn = wn * wo;
 57             }
 58             //注意是合并所以要走2t步
 59             l = r + t;
 60             r = l + t;
 61         }
 62     }
 63 }
 64 //离散傅里叶变换
 65 void DFT(Num *x, int len, int loglen){
 66     int t = (1<<loglen);
 67     for (int i = 0; i < loglen; i++){
 68         t >>= 1;
 69         int l = 0, r = l + t;
 70         while (l < len){
 71             Num a, b, wn(1, 0), wo(cos(Pi / t), -sin(Pi / t));
 72             for (int j = l; j < l + t; j++){
 73                 a = x[j] + x[j + t];
 74                 b = (x[j] - x[j + t]) * wn;
 75                 x[j] = a;
 76                 x[j + t] = b;
 77                 wn = wn * wo;
 78             }
 79             l = r + t;
 80             r = l + t;
 81         }
 82     }
 83     change(x, len, loglen);
 84     for (int i= 0; i < len; i++) x[i].a /= len;
 85 }
 86 int solve(char *a, char *b){
 87     int len1, len2, len, loglen;
 88     int t, over;
 89     len1 = strlen(a) << 1;
 90     len2 = strlen(b) << 1;
 91     len = 1;
 92     loglen = 0;
 93     while (len < len1) len <<= 1, loglen++;
 94     while (len < len2) len <<= 1, loglen++;
 95     //处理len1
 96     for (int i = 0; i < len; i++){
 97         if (a[i]) x1[i].a = a[i] - ‘0‘, x1[i].b = 0;
 98         else x1[i].a = x1[i].b = 0;
 99     }
100     for (int i = 0; i < len; i++){
101         if (b[i]) x2[i].a = b[i] - ‘0‘, x2[i].b = 0;
102         else x2[i].a = x2[i].b = 0;
103     }
104     FFT(x1, len, loglen);
105     FFT(x2, len, loglen);
106     for (int i = 0; i < len; i++) x1[i] = x1[i] * x2[i];
107
108     DFT(x1, len, loglen);
109     over = len = 0;
110     //转换成十进制的整数
111     for (int i = ((len1 + len2) / 2) - 2; i >= 0; i--){
112         t = x1[i].a + over + 0.5;
113         a[len++] = t % 10;
114         over = t / 10;
115     }
116     while (over){
117         a[len++] = over % 10;
118         over /= 10;
119     }
120     return len;
121 }
122 //输出
123 void print(char *str, int len){
124      for(len--; len>=0 && !str[len];len--);
125     if(len < 0) putchar(‘0‘);
126     else for(;len>=0;len--) putchar(str[len]+‘0‘);
127     printf("\n");
128 }
129 char a[MAXN] , b[MAXN];
130
131 int main() {
132
133     //char a[MAXN], b[MAXN];
134    while(scanf("%s%s", a, b) != EOF) {
135           print(a, solve(a, b));
136           memset(a, 0, sizeof(a));
137           memset(b, 0, sizeof(b));
138     }
139     //printf("%.10lf\n", Pi);
140    return 0;
141 }

时间: 2024-08-07 00:14:23

【HDU1402】【FFT】A * B Problem Plus的相关文章

【FFT】专题总结

学了若干天终于学(bei)会了传说中的法法塔 感觉也没那么难用嘛 fft快速傅里叶变换 在大表课件上写就是解决高精乘的工具 其实很有理有据 fft就是用复数的折半引理优化两个多项式相乘的高端东西 他能使O(n^2)的多项式相乘优化到O(nlogn) 听ak说这也是比较模板的东西 也就不去理解什么证明了(其实是我看了半天看不懂TAT) 贴个代码吧(史上最短总结233- -) 1 int bit_rev(int t,int n){ 2 int res=0; 3 for (int i=0;i<n;i+

【BZOJ3527】【FFT】力

[问题描述]给出n个数qi,给出Fj的定义如下:令Ei=Fi/qi.试求Ei.[输入格式]输入文件force.in包含一个整数n,接下来n行每行输入一个数,第i行表示qi.[输出格式]输出文件force.out有n行,第i行输出Ei.与标准答案误差不超过1e-2即可.[样例输入]54006373.88518415375036.4357591717456.4691448514941.0049121410681.345880[样例输出]-16838672.6933439.7937509018.566

BZOJ3527 [Zjoi2014]力 【fft】

题目 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. 输入格式 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. 输出格式 n行,第i行输出Ei.与标准答案误差不超过1e-2即可. 输入样例 5 4006373.885184 15375036.435759 1717456.469144 8514941.004912 1410681.345880 输出样例 -16838672.693 3439.793 7509018.566 4595686.886 1090304

【FFT】快速傅里叶变换

[FFT]快速傅里叶变换 一.复数 1.定义 复数:设 $a$,$b$ 为实数,$i^{2}=−1$ ,形如 $a+bi$ 的数叫复数,其中 $i$ 被称为虚数单位,复数域是目前已知最大的域 在复平面中,$x$ 代表实数,$y$ 轴(除原点外的点)代表虚数,从原点 $(0,0)$ 到 $(a,b)$ 的向量表示复数 $a+bi$ 模长:从原点 $(0,0)$ 到点 $(a,b)$ 的距离,即 $\sqrt{a^2+b^2}$ 幅角:假设以逆时针为正方向,从 $x$ 轴正半轴到已知向量的转角的有向

【UOJ#50】【UR #3】链式反应(分治FFT,动态规划)

[UOJ#50][UR #3]链式反应(分治FFT,动态规划) 题面 UOJ 题解 首先把题目意思捋一捋,大概就是有\(n\)个节点的一棵树,父亲的编号大于儿子. 满足一个点的儿子有\(2+c\)个,其中\(c\in A\),且\(c\)个儿子是叶子,另外\(2\)个存在子树,且两种点的链接的边是不同的,求方案数. 那么就考虑一个暴力\(dp\),设\(f[i]\)表示有\(i\)个节点的树的个数. 那么枚举它两个有子树的子树大小,然后把编号给取出来,得到: \[f[i]=\frac{1}{2}

【BZOJ】【2194】快速傅里叶之二

FFT c[k]=sigma a[i]*b[i-k] 这个形式不好搞…… 而我们熟悉的卷积的形式是这样的 c[k]=sigma a[i]*b[k-i]也就是[下标之和是定值] 所以我们将a数组反转一下就可以卷积了=.= 1 /************************************************************** 2 Problem: 2194 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:20

【排序】【规律】Codeforces Round #254 (Div. 2) - D. Rooter&#39;s Song

D. DZY Loves FFT Source http://codeforces.com/contest/445/problem/D Description Wherever the destination is, whoever we meet, let's render this song together. On a Cartesian coordinate plane lies a rectangular stage of size w?×?h, represented by a re

【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。

[SIGGRAPH 2015][巫师3 狂猎 The Witcher 3: Wild Hunt ]顶级的开放世界游戏的实现技术 作者:西川善司 日文链接  http://www.4gamer.net/games/202/G020288/20150811091/ 计算机图形和交互技术的学术大会[SIGGRAPH 2015],在北美时间的8月9日到13日召开了. SIGGRAPH 2015的会场,因E3而被熟知的洛杉矶会议中心 SIGGRAPH有着美国洛杉矶和以外地区交替举办的惯例,2014年是在加

【Windows10&nbsp;IoT开发系列】配置篇

原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry Pi.MinnowBoard和Galileo平台上的核心版.本文重点针对Raspberry Pi平台的Windwos10 IoT配置做介绍. Windows 10 IoT Editions ​一:设置你的电脑. 注:​开发Windows10 IoT的电脑需要Visual Studio 2015.

【Windows10&nbsp;IoT开发系列】PowerShell的相关配置

原文:[Windows10 IoT开发系列]PowerShell的相关配置 可使用 Windows PowerShell 远程配置和管理任何 Windows 10 IoT 核心版设备.PowerShell 是基于任务的命令行 Shell 和脚本语言,专为进行系统管理而设计. 1.​启动 PowerShell (PS) 会话 注:若要使用装有Windows10 IoT Core设备启动PS会话,首先需要在主机电脑与设备之间创建信任关系. ​启动 Windows IoT 核心版设备后,与该设备相连的