洛谷 P1919 【模板】A*B Problem升级版 fft

原创 2018年04月16日 11:14:08

题目描述

给出两个n位10进制整数x和y,你需要计算x*y。

输入输出格式

输入格式:
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

输出格式:
输出一行,即x*y的结果。(注意判断前导0)

输入输出样例

输入样例#1:
1
3
4
输出样例#1:
12
说明

数据范围:

n<=60000

来源:bzoj2179

分析:可以把一个正整数看做是一个多项式,其中x=10(其实也可以是10^k),然后跑fft,跑出来之后好进行进位处理。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

const int maxn=240007;
const double pi=acos(-1);

using namespace std;

struct rec{
    double x,y;
};

rec operator + (rec a,rec b) {return (rec){a.x+b.x,a.y+b.y};}
rec operator - (rec a,rec b) {return (rec){a.x-b.x,a.y-b.y};}
rec operator * (rec a,rec b) {return (rec){a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y};}

rec a[maxn],b[maxn];
char s[maxn];
int r[maxn],ans[maxn];
int n,l,p;

void fft(rec *a,int f)
{
    for (int i=0;i<l;i++)
    {
        if (i<r[i]) swap(a[i],a[r[i]]);
    }
    for (int i=2;i<=l;i*=2)
    {
        rec wn=(rec){cos(2*pi/i),f*sin(2*pi/i)};
        for (int j=0;j<l;j+=i)
        {
            rec w=(rec){1,0};
            for (int k=0;k<i/2;k++)
            {
                rec u=a[j+k],v=w*a[j+k+i/2];
                a[j+k]=u+v;
                a[j+k+i/2]=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'; 
    l=1;p=0;
    while (l<(n*2)) l*=2,p++;
    for (int i=0;i<l;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));    
    fft(a,1);
    fft(b,1);
    for (int i=0;i<l;i++) a[i]=a[i]*b[i];
    fft(a,-1);
    int num;
    for (int i=0;i<l+3;i++)
    {
        ans[i]=ans[i]+trunc(a[i].x/l+0.233);
        if (ans[i]>0) num=i;
        ans[i+1]=ans[i]/10;
        ans[i]=ans[i]%10;
    }   
    for (int i=num;i>=0;i--) printf("%d",ans[i]);
}
版权声明:2333 https://blog.csdn.net/liangzihao1/article/details/79958137

模板,FFT 快速傅里叶变化

大神的模板。。
  • utoppia
  • utoppia
  • 2014-04-21 20:17:32
  • 4037

快速傅里叶(FFT)题表

前言 最近终于学了FFT 以前被scy逼着学过一次没有学会,这次终于好一点了 在这里大致放一下一些FFT的题目 题表 uoj34 多项式乘法,这个估计是大多数人的入门题了吧 code...
  • qq_36797743
  • qq_36797743
  • 2017-11-23 15:46:29
  • 435

【Luogu1919】 A*B Problem升级版(FFT)

题面戳我题解把每个数都直接看做一个多项式,每一位就是一项 现在求用FFT求出卷积 然后考虑一下进位就可以啦#include #include #include #include #include ...
  • qq_30974369
  • qq_30974369
  • 2017-10-02 19:44:47
  • 139

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

这其实就是一道裸的FFT 核心思想:把两个数拆成两个多项式用FFT相乘,再反序输出 py解法如下: input() print(int(input())*int(input())) 皮一下...
  • EZharry
  • EZharry
  • 2018-04-20 21:13:58
  • 9

xijtuoj wmq的A×B Problem FFT+原根

题目连接点这里 神套路题 因为m为素数所以必定有原根,设为x, 根据原根那套理论,x^(0)mod m,x^(1)mod m,,,,x^(m-2)mod m,的值互不相同,取遍 1到m-1.所以我们可...
  • qq_30927651
  • qq_30927651
  • 2017-04-25 19:06:10
  • 293

高精度加法 洛谷 P1601 A+B Problem(高精)

高精度加法 洛谷 P1601 A+B Problem(高精)平常一般不用高精度,结果连高精度加法都不会。。现在开始学习一下,毕竟是极其基础的东西。。。洛谷 P1601 A+B Problem(高...
  • zhihuizhishen
  • zhihuizhishen
  • 2016-10-19 20:37:53
  • 259

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

题意:给你一堆数,然后求ai+aj=ak的组成的(i,j,k)对有多少个,并且保证i,j,k下标互不相同。题解:num[k]表示(ai,aj)=k的个数。然后将a[i]+a[i]的那种重复的去掉。然后...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016-10-07 20:47:39
  • 1837

洛谷 P1001 A+B Problem(学会改变——向C++进发!)

题目 题解 代码题目输入两个整数a,b,输出它们的和(|a|,|b|
  • yjy_aii
  • yjy_aii
  • 2017-02-25 11:40:58
  • 608

洛谷 1303——A*B Problem

题目描述输入二个正整数x0,y0(2
  • SSL_ZZY
  • SSL_ZZY
  • 2017-02-12 10:37:25
  • 264

【模拟】洛谷 P1001 A+B Problem

题目描述输入两个整数a,b,输出它们的和(|a|,|b|
  • hyj542682306
  • hyj542682306
  • 2017-04-24 16:23:38
  • 204
收藏助手
不良信息举报
您举报文章:洛谷 P1919 【模板】A*B Problem升级版 fft
举报原因:
原因补充:

(最多只允许输入30个字)