A * B Problem Plus(fft)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1402

hdu_1402:A * B Problem Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15419    Accepted Submission(s):
3047

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

题解: 练习用fft实现大数的乘法达到O(nlog(n))的算法,两个数相乘看成是两个多项式的乘法,这样多项式中的x=10,fft套用模板即可

给出代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 using namespace std;
  6 const int MAX=300005;
  7 const double PI=acos(-1.0),eps=1e-8;;
  8 double cof1[MAX], cof2[MAX];
  9 int n, k, permutation[MAX];
 10 char s1[MAX],s2[MAX];
 11 int ans[MAX];
 12 struct complex {//复数
 13     double r, v;
 14     complex operator + (complex& obj) {
 15         complex temp;
 16         temp.r = r + obj.r;
 17         temp.v = v + obj.v;
 18         return temp;
 19     }
 20     complex operator - (complex& obj) {
 21         complex temp;
 22         temp.r = r - obj.r;
 23         temp.v= v - obj.v;
 24         return temp;
 25     }
 26     complex operator * ( complex& obj) {
 27         complex temp;
 28         temp.r = r*obj.r - v*obj.v;
 29         temp.v = r*obj.v + v*obj.r;
 30         return temp;
 31     }
 32 } p1[MAX], p2[MAX], omiga[MAX], result1[MAX], result2[MAX];
 33 void caculate_permutation(int s, int interval, int w, int next) {
 34     if(interval==n) {
 35         permutation[w] = s;
 36         return ;
 37     }
 38     caculate_permutation(s,interval*2, w, next/2);
 39     caculate_permutation(s+interval, interval*2, w+next, next/2);
 40 }
 41 void fft(complex transform[], complex p[]) {
 42     int i, j, l, num, m;
 43     complex temp1, temp2;
 44     for(i=0; i<n; i++)transform[i] = p[ permutation[i] ] ;
 45     num = 1, m = n;
 46     for(i=1; i<=k; i++) {
 47         for(j=0; j<n; j+=num*2)
 48             for(l=0; l<num; l++)
 49                 temp2 = omiga[m*l]*transform[j+l+num],
 50                         temp1 = transform[j+l],
 51                                 transform[j+l] = temp1 + temp2,
 52                                                  transform[j+l+num] = temp1 - temp2;
 53         num*=2,m/=2;
 54     }
 55 }
 56 void polynomial_by(int n1,int n2) {//多项式乘法,cof1、cof2保存的是a[0],a[1]..a[n-1]的值(a[i]*x^i)
 57     int i;
 58     double angle;
 59     k = 0, n = 1;
 60     while(n<n1+n2-1)k++,n*=2;
 61     for(i=0; i<n1; i++)p1[i].r = cof1[i], p1[i].v = 0;
 62     while(i<n)p1[i].r = p1[i].v = 0, i++;
 63     for(i=0; i<n2; i++)p2[i].r = cof2[i], p2[i].v = 0;
 64     while(i<n)p2[i].r = p2[i].v = 0, i++;
 65     caculate_permutation(0,1,0,n/2);
 66     angle = PI/n;
 67     for(i=0; i<n; i++)omiga[i].r = cos(angle*i), omiga[i].v = sin(angle*i);
 68     fft(result1,p1);
 69     fft(result2,p2);
 70     for(i=0; i<n; i++)result1[i]= result1[i]*result2[i];
 71     for(i=0; i<n; i++)omiga[i].v = -omiga[i].v;
 72     fft(result2, result1);
 73     for(i=0; i<n; i++)result2[i].r/=n;
 74     i = n -1;
 75     while(i&&fabs(result2[i].r)<eps)i--;
 76     n = i+1;
 77     while(i>=0) ans[i]=(int)(result2[i].r+0.5), i--;
 78 }
 79 int main() {
 80     while(scanf("%s",s1)!=EOF){
 81         scanf("%s",s2);
 82         int n1=strlen(s1),n2=strlen(s2);
 83         for(int i=0;i<n1;i++){
 84             cof1[i]=s1[n1-1-i]-‘0‘;
 85         }
 86         for(int i=0;i<n2;i++){
 87             cof2[i]=s2[n2-1-i]-‘0‘;
 88         }
 89         memset(ans,0,sizeof(ans));
 90         polynomial_by(n1,n2);
 91         for(int i=0;i<n;i++){
 92             if(ans[i]>=10){
 93                 ans[i+1]+=ans[i]/10;
 94                 ans[i]%=10;
 95             }
 96         }
 97         while(ans[n]>0){
 98             if(ans[n]>=10){
 99                 ans[n+1]+=ans[n]/10;
100                 ans[n]%=10;
101             }
102             n++;
103         }
104         for(int i=n-1;i>=0;i--){
105             putchar(‘0‘+ans[i]);
106         }
107         puts("");
108     }
109     return 0;
110 }
时间: 2024-10-10 21:10:44

A * B Problem Plus(fft)的相关文章

HDU 1402 A * B Problem Plus 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

HDU1402 A * B Problem Plus FFT

分析:网上别家的代码都分析的很好,我只是给我自己贴个代码,我是kuangbin的搬运工 一点想法:其实FFT就是快速求卷积罢了,当小数据的时候我们完全可以用母函数来做,比如那种硬币问题 FFT只是用来解决数据规模较大时的办法,可以达到nlogn的效率,大体原理就是运用了n次单位复根的折半引理 具体可以看算法导论 高度仰慕kuangbin大神的模板,实在是不想自己写 对于这个题,我们10^k的系数看成多项式系数,然后求卷积,进位就好了 #include <stdio.h> #include &l

洛谷.1919.[模板]A乘B Problem升级版(FFT)

题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 //n位*n位最多就只有2n位了 //论putchar的速度..还是快的 #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar

HDU - 1402 A * B Problem Plus FFT裸题

http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$ 题解: 显然...用字符串模拟的大数或者压位的大数是无法胜任这种计算的.... 然后,2个大整数相乘,可以理解为卷积,所以就用快速傅里叶变换(FFT)来加速他 模板题 简单总结一下对FFT的认知: FFT用于算卷积,卷积可以理解为两个多项式相乘显然复杂度是$O(n^2)$的 但是fft可以优化为$O(nlogn)$如何优化,考虑

XJTUOJ wmq的A&#215;B Problem FFT

wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简单的问题. wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b.现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个. 输入 第一行为测试数据的组数. 对于每组测试数据,第一行为2个正整数n,

【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 Out

2016 acm香港网络赛 A题. A+B Problem (FFT)

原题地址:https://open.kattis.com/problems/aplusb FFT代码参考kuangbin的博客:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html A+B Problem Given N integers in the range [−50000,50000], how many ways are there to pick three integers ai, aj, ak, such

hdu----(1402)A * B Problem Plus(FFT模板)

A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12665    Accepted Submission(s): 2248 Problem Description Calculate A * B. Input Each line will contain two integers A and B. P

hdu 1402 A * B Problem Plus (FFT + 大数相乘)

A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13456    Accepted Submission(s): 2401 Problem Description Calculate A * B. Input Each line will contain two integers A and B.