zoukankan      html  css  js  c++  java
  • bzoj2179 FFT快速傅立叶

    2179: FFT快速傅立叶

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 4155  Solved: 2222
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

    Output

    输出一行,即x*y的结果。

    Sample Input

    1
    3
    4

    Sample Output

    12
    数据范围:
    n<=60000
    分析:终于把fft给学了. 推荐一篇文章:传送门
     
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 2e5+5;
    const double pai = acos(-1.0);
    
    int len1,len2,len,res[maxn];
    char s1[maxn],s2[maxn];
    struct node
    {
        double real, imag;
        node(double real = 0.0, double imag = 0.0)
        {
            this->real = real, this->imag = imag;
        }
        node operator - (const node&elem) const
        {
            return node(this->real - elem.real, this->imag - elem.imag);
        }
        node operator + (const node&elem) const
        {
            return node(this->real + elem.real, this->imag + elem.imag);
        }
        node operator * (const node&elem) const
        {
            return node(this->real * elem.real - this->imag * elem.imag, this->real * elem.imag + this->imag * elem.real);
        }
        void set(double real = 0.0, double imag = 0.0)
        {
            this->real = real, this->imag = imag;
        }
    } A[maxn],B[maxn];
    
    void pre()
    {
        len1 = strlen(s1),len2 = strlen(s2);
        int maxx = max(len1,len2);
        len = 1;
        while (len < (maxx << 1))
            len <<= 1;
        for (int i = 0; i < len1; i++)
            A[i].set(s1[len1 - i - 1] - '0',0);
        for (int i = 0; i < len2; i++)
            B[i].set(s2[len2 - i - 1] - '0',0);
        for (int i = len1; i < len; i++)
            A[i].set();
        for (int i = len2; i < len; i++)
            B[i].set();
    }
    
    void Swap(node &a,node &b)
    {
        node temp = a;
        a = b;
        b = temp;
    }
    
    void zhuan(node y[])
    {
        for (int i = 1, j = len >> 1,k; i < len - 1; i++)
        {
            if (i < j)
                Swap(y[i],y[j]);
            k = len >> 1;
            while (j >= k)
            {
                j -= k;
                k >>= 1;
            }
            if (j < k)
                j += k;
        }
    }
    
    void FFT(node y[],int op)
    {
        zhuan(y);
        for (int h = 2; h <= len; h <<= 1)
        {
            node temp(cos(op * 2 * pai / h),sin(op * 2 * pai / h));
            for (int i = 0; i < len; i += h)
            {
                node W(1,0);
                for (int j = i; j < i + h / 2; j++)
                {
                    node u = y[j];
                    node t = W * y[j + h / 2];
                    y[j] = u + t;
                    y[j + h / 2] = u - t;
                    W = W * temp;
                }
            }
        }
        if (op == -1)
            for (int i = 0; i < len; i++)
                y[i].real /= len;
    }
    
    void solve(node *A,node *B)
    {
        FFT(A,1);
        FFT(B,1);
        for (int i = 0; i < len; i++)
            A[i] = A[i] * B[i];
        FFT(A,-1);
        for (int i = 0; i < len; i++)
            res[i] = (int)(A[i].real + 0.5);
    }
    
    void calc(int *a)
    {
        for (int i = 0; i < len; i++)
        {
            res[i + 1] += res[i] / 10;
            res[i] %= 10;
        }
        while (--len && res[len] == 0);
    }
    
    void print(int *a)
    {
        for (int i = len; i >= 0; i--)
            putchar(a[i] + '0');
        printf("
    ");
    }
    
    int main()
    {
        int nn;
        scanf("%d",&nn);
        getchar();
        gets(s1);
        gets(s2);
        pre();
        solve(A,B);
        calc(res);
        print(res);
    
        return 0;
    }
  • 相关阅读:
    Floyd_Warshall算法
    Bellman_Ford算法
    深度优先搜索
    广度优先搜索
    贪心算法_活动选择
    动态规划_0-1背包问题
    算法导论_动态规划_最长回文子序列
    算法导论_动态规划_最长公共子序列
    动态规划解决分割问题
    2016 Google中国开发者大会游记
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8638924.html
Copyright © 2011-2022 走看看