P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

思路还是挺简单的。

输入的2个数 \(a=\overline{a_n a_{n-1} a_{n-2}\cdots a_{0}}\) , \(b=\overline{b_m b_{m-1} b_{m-2}\cdots b_{0}}\)

直接把 \(a_i\) 和 \(b_i\) 看做多项式 A 和 B 的系数,做多项式乘法即可。因为 a ,b 可以看做以 \(a_i,b_i\) 为系数,自变量为10的多项式的值,乘完后的多项式的系数就知道了,再将 \(x=10\) 带入,(就是进位的过程),就可解了。(也可以把这一过程看做加速朴素的高精度乘法,因为 \(a_i \times x^i + b_j \times x^j =a_i\times b_j \times x^{i+j}\) ,高精度乘法模拟的也是这个过程。)

Code

#include<bits/stdc++.h>
using namespace std;
const int N=3000006;
const double pi=acos(-1.0);
struct cp {
    double x,y;
    cp (double xx=0,double yy=0) {
        x=xx,y=yy;
    }
} a[N],b[N];
cp operator + (const cp &a,const cp &b) {
    return cp(a.x+b.x,a.y+b.y);
}
cp operator - (const cp &a,const cp &b) {
    return cp(a.x-b.x,a.y-b.y);
}
cp operator * (const cp &a,const cp &b) {
    return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
int n,m,lim=1,l,rev[N];
void fft(cp *a,int o) {
    for(int i=0; i<lim; ++i)
        if(i<rev[i])swap(a[i],a[rev[i]]);
    for(int i=1; i<lim; i<<=1) {
        cp wn(cos(pi/i),o*sin(pi/i));
        for(int j=0; j<lim; j+=(i<<1)) {
            cp w0(1,0);
            for(int k=0; k<i; ++k,w0=w0*wn) {
                cp X=a[j+k],Y=w0*a[i+j+k];
                a[j+k]=X+Y;
                a[i+j+k]=X-Y;
            }
        }
    }
}
char s1[N],s2[N];
int ans[N+N],tot;
int main() {
    scanf("%s%s",s1,s2);
    n=strlen(s1)-1;m=strlen(s2)-1;
    for(int i=0; i<=n; ++i)a[i].x=s1[n-i]-'0';
    for(int i=0; i<=m; ++i)b[i].x=s2[m-i]-'0';
    for(; lim<=n+m; lim<<=1,++l);
    for(int i=0; i<lim; ++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    fft(a,1);fft(b,1);
    for(int i=0; i<lim; ++i)a[i]=a[i]*b[i];
    fft(a,-1);
    for(int i=0; i<lim; ++i)
    {
        ans[i]+=(int)(a[i].x/lim+0.5);
        if(ans[i]>=10)ans[i+1]+=ans[i]/10,ans[i]%=10;
    }
    while(!ans[lim]&&lim)--lim;
    for(int i=lim;i>=0;--i)
        printf("%d",ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/zzctommy/p/12332453.html

时间: 2024-08-26 17:34:02

P1919 【模板】A*B Problem升级版(FFT快速傅里叶)的相关文章

洛谷.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

FFT快速傅里叶模板

FFT快速傅里叶模板-- /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < 2 * len1 || len < 2 * len2) len <<= 1; 2. for i=0 to len1-1 : x1[i](f(i),0) for i=len1 to len-1 : x1[i](0.0) g(x) is same..... 3. fft(x1,len,1) ff

洛谷P3803 【模板】多项式乘法(FFT)

P3803 [模板]多项式乘法(FFT) 题目背景 这是一道FFT模板题 题目描述 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输入输出格式 输入格式: 第一行2个正整数n,m. 接下来一行n+1个数字,从低到高表示F(x)的系数. 接下来一行m+1个数字,从低到高表示G(x))的系数. 输出格式: 一行n+m+1个数字,从低到高表示F(x)∗G(x)的系数. 输入输出样例 输入样例#1: 复制 1 2 1 2 1 2 1 输出样例#1: 复制 1

luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

模板 嗯 做多项式乘法,进位 没了 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define pi acos(-1.0) inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9')c = getchar(); while(c <= '9'

luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶)|FFT

题目描述 给你两个正整数 a,b,求 a×b. 输入格式 第一行一个正整数,表示 a: 第二行一个正整数,表示 b. 输出格式 输出一行一个整数表示答案. #include<cmath> #include<string> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int _=4e6+10; const double Pi=a

[Luogu 1919]【模板】A*B Problem升级版(FFT快速傅里叶)

Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果.(注意判断前导0) Sample Input 134 Sample Output 12 HINT n<=60000 题解 A*B Problem.和 A+B Problem 一样简单. 1 input() and print(int(input()) * int(input()

【BZOJ】【2179】FFT快速傅里叶

FFT 做的第二道用到FFT的……好吧其实还是模板题-_-b 百度上说好像分治也能做……不过像FFT这种敲模板的还是省事=.= 1 /************************************************************** 2 Problem: 2179 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1236 ms 7 Memory:9184 kb 8 *********************

HDU1402 A * B Problem Plus FFT

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

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 Calculat