Code[VS] 3123 高精度练习之超大整数乘法

FFT 做 高精度乘法

  1 #include <bits/stdc++.h>
  2
  3 const double pi = acos(-1);
  4
  5 struct complex
  6 {
  7     double a, b;
  8
  9     inline complex(
 10         double _a = 0,
 11         double _b = 0)
 12     {
 13         a = _a;
 14         b = _b;
 15     }
 16
 17     inline friend complex operator +
 18     (const complex &a, const complex &b)
 19     {
 20         return complex(a.a + b.a, a.b + b.b);
 21     }
 22
 23     inline friend complex operator -
 24     (const complex &a, const complex &b)
 25     {
 26         return complex(a.a - b.a, a.b - b.b);
 27     }
 28
 29     inline friend complex operator *
 30     (const complex &a, const complex &b)
 31     {
 32         return complex(a.a*b.a - a.b*b.b, a.a*b.b + a.b*b.a);
 33     }
 34
 35     inline friend complex & operator +=
 36     (complex &a, const complex &b)
 37     {
 38         return a = a+b;
 39     }
 40
 41     inline friend complex & operator -=
 42     (complex &a, const complex &b)
 43     {
 44         return a = a-b;
 45     }
 46
 47     inline friend complex & operator *=
 48     (complex &a, const complex &b)
 49     {
 50         return a = a*b;
 51     }
 52 };
 53
 54 inline complex alpha(double a)
 55 {
 56     return complex(cos(a), sin(a));
 57 }
 58
 59 typedef std::vector<complex> vec;
 60
 61 vec FFT(const vec &a)
 62 {
 63     int n = a.size();
 64
 65     if (n == 1)return a;
 66
 67     complex w_k(1, 0);
 68     complex w_n = alpha(pi*2/n);
 69
 70     vec ar[2], yr[2], y(n);
 71
 72     for (int i = 0; i < n; ++i)
 73         ar[i & 1].push_back(a[i]);
 74
 75     for (int i = 0; i < 2; ++i)
 76         yr[i] = FFT(ar[i]);
 77
 78     for (int i = 0; i < n/2; ++i, w_k *= w_n)
 79     {
 80         y[i] = yr[0][i] + w_k * yr[1][i];
 81         y[i + n/2] = yr[0][i] - w_k * yr[1][i];
 82     }
 83
 84     return y;
 85 }
 86
 87 vec IFFT(const vec &a)
 88 {
 89     int n = a.size();
 90
 91     if (n == 1)return a;
 92
 93     complex w_k(1, 0);
 94     complex w_n = alpha(-pi*2/n);
 95
 96     vec ar[2], yr[2], y(n);
 97
 98     for (int i = 0; i < n; ++i)
 99         ar[i & 1].push_back(a[i]);
100
101     for (int i = 0; i < 2; ++i)
102         yr[i] = IFFT(ar[i]);
103
104     for (int i = 0; i < n/2; ++i, w_k *= w_n)
105     {
106         y[i] = yr[0][i] + w_k * yr[1][i];
107         y[i + n/2] = yr[0][i] - w_k * yr[1][i];
108     }
109
110     return y;
111 }
112
113 char s1[100005]; int len1;
114 char s2[100005]; int len2;
115
116 vec v1, v2, p1, p2, mul, ans;
117
118 signed main(void)
119 {
120     scanf("%s", s1); len1 = strlen(s1);
121     scanf("%s", s2); len2 = strlen(s2);
122
123     int len = len1 + len2;
124
125     while (len != (len&-len))++len;
126
127     for (int i = len1 - 1; ~i; --i)v1.push_back(complex(s1[i] - ‘0‘, 0));
128     for (int i = len2 - 1; ~i; --i)v2.push_back(complex(s2[i] - ‘0‘, 0));
129
130     while ((int)v1.size() < len)v1.push_back(complex());
131     while ((int)v2.size() < len)v2.push_back(complex());
132
133     p1 = FFT(v1);
134     p2 = FFT(v2);
135
136     for (int i = 0; i < len; ++i)
137         mul.push_back(p1[i] * p2[i]);
138
139     ans = IFFT(mul);
140
141     std::vector<int> ret;
142
143     for (int i = 0; i < len; ++i)
144         ret.push_back((int)round(ans[i].a / len));
145
146     for (int i = 0; i < len; ++i)
147         if (ret[i] >= 10)
148         {
149             ret[i + 1] += ret[i] / 10;
150             ret[i] %= 10;
151         }
152
153     while (ret.size() != 1 && !ret[ret.size() - 1])
154         ret.pop_back();
155
156     for (int i = ret.size() - 1; i >= 0; --i)
157         putchar(‘0‘ + ret[i]);
158     putchar(‘\n‘);
159 }

@Author: YouSiki

时间: 2024-10-01 01:29:15

Code[VS] 3123 高精度练习之超大整数乘法的相关文章

【CodeVS 3123】高精度练习之超大整数乘法

第一次写法法塔,,,感到威力无穷啊 看了一上午算导就当我看懂了?PS:要是机房里能有个清净的看书环境就好了 FFT主要是用了巧妙的复数单位根,复数单位根在复平面上的对称性使得快速傅立叶变换的时间复杂度空降为O(nlogn)←个人的愚蠢理解请随意吐槽 具体的我就不说了,算导上都说得很清楚,说得好像有人会听我说什么似的 模板在这里↓ CodeVS 3123: #include<cmath> #include<cstdio> #include<cstring> #includ

【CodeVS 3123】 高精度练习之超大整数乘法

RE了2发   init竟然会开小....... 1 #include <cstdio> 2 #include <algorithm> 3 #include <complex> 4 #include <iostream> 5 #include <cmath> 6 using namespace std; 7 const  double PI= acos(-1); 8 int init[100000*4+10]; 9 #define C compl

codevs 3119 高精度练习之大整数开根 (各种高精+压位)

/* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#2.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms 测试点#3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#4.in 结果:AC 内存使用量: 256kB 时间使用量: 10ms 测试点#5.in 结果:AC 内

JavaScript超大整数加法

什么是「超大整数」? JavaScript 采用 IEEE754标准 中的浮点数算法来表示数字 Number. 我也没花时间去详细了解 IEEE754标准 ,但对于处理超大整数,了解下面的几个知识点就足够了. 首先,JavaScript 实际上可以表示的最大数是: 1.7976931348623157e+308 Number.MAX_VALUE; // 1.7976931348623157e+308 虽然这个数可以正确表示出来,但会存在「精度丢失」的问题. 那什么是「精度丢失」? 我们看看下面的

如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算

package interview_10_10; import org.junit.Test; public class T1 { /** * 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算). */ @Test public void test1() { String number1 = "4324328732789"; String number2 = "2383244324324325898

POJ 1001 解题报告 高精度大整数乘法模版

题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于错误的判断还不够严厉. 对边界情况的讨论其实应该是思维严密的表现,当然这并不能表明我写的一点错误都没有,只是多多分析一下还是很有好处的. #include <iostream> #include <fstream> #include <string> #include &l

C语言简短源码计算超大整数的阶乘

把写代码过程中比较好的代码段做个记录,下边资料是关于C语言简短计算超大整数的阶乘的代码,应该对小伙伴们有较大用处. int a[100000]={1},n,i,c,m=1;main(){scanf("%d",&n);for(;n;n--){for(c=i=0;i<m||c;)}for(;m;)putch(a[--m]+48);} 原文地址:https://blog.51cto.com/14131177/2377184

C语言(7)--高精度加法、减法、乘法、今天是星期几、四位平方数、候选人选票问题

1.高精度加法.减法.乘法 #include <stdio.h> #include <string.h> #include <malloc.h> void plus(char *a,char *b,char *c);//自定义高精度加法函数 void sub(char *a,char *b,char *c);//自定义高精度减法函数 void multiply(char *a,char *b,char *c);//自定义高精度乘法函数 int main() { char

大整数乘法python3实现

由于python具有无限精度的int类型,所以用python实现大整数乘法是没意义的,但是思想是一样的.利用的规律是:第一个数的第i位和第二个数大第j位相乘,一定累加到结果的第i+j位上,这里是从0位置开始算的.代码如下: import sys def list2str(li): while li[0]==0: del li[0] res='' for i in li: res+=str(i) return res def multi(stra,strb): aa=list(stra) bb=l