zoukankan      html  css  js  c++  java
  • 2016级算法第六次上机-B.ModricWang's FFT : EASY VERSION

    1114 ModricWang's FFT EASY VERSION

    思路

    利用FFT做大整数乘法,实际上是把大整数变成多项式,然后做多项式乘法。

    例如,对于(1234),改写成(f(x)=1*x^3+2*x^2+3*x+4),那么(x=10)处的值就是原数。类似的,对于输入的两个大整数,转换为(f(x))(g(x)) ,利用FFT求出(h(x)=f(x)*g(x)) ,此时(h(10)) 就是乘积。

    代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <random>
    #include <functional>
    #include <complex>
    
    using namespace std;
    const auto PI = acos(-1.0);
    typedef complex<double> Complex;
    
    void change(Complex y[], int len) {
        int i, j, k;
        for (i = 1, j = len / 2; i < len - 1; i++) {
            if (i < j) swap(y[i], y[j]);
            k = len / 2;
            while (j >= k) {
                j -= k;
                k /= 2;
            }
            if (j < k)j += k;
        }
    }
    
    
    void fft(Complex y[], int len, int on) {
        change(y, len);
        for (int h = 2; h <= len; h <<= 1) {
            Complex wn(cos(-on * 2 * PI / h), sin(-on * 2 * PI / h));
            for (int j = 0; j < len; j += h) {
                Complex w(1, 0);
                for (int k = j; k < j + h / 2; k++) {
                    Complex u = y[k];
                    Complex t = w * y[k + h / 2];
                    y[k] = u + t;
                    y[k + h / 2] = u - t;
                    w = w * wn;
                }
            }
        }
        if (on == -1)
            for (int i = 0; i < len; i++)
                y[i] = Complex(y[i].real() / len, y[i].imag());
    }
    
    const int MAXN = 200010;
    Complex x1[MAXN], x2[MAXN];
    string str1, str2;
    int sum[MAXN];
    
    
    int main() {
    #ifdef ONLINE_JUDGE
        ios_base::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
    #endif
        cin >> str1 >> str2;
        auto len1 = str1.length();
        auto len2 = str2.length();
        auto len = 1;
        while (len < len1 * 2 || len < len2 * 2)len <<= 1;
        for (auto i = 0; i < len1; i++)
            x1[i] = Complex(str1[len1 - 1 - i] - '0', 0);
        for (auto i = len1; i < len; i++)
            x1[i] = Complex(0, 0);
        for (int i = 0; i < len2; i++)
            x2[i] = Complex(str2[len2 - 1 - i] - '0', 0);
        for (auto i = len2; i < len; i++)
            x2[i] = Complex(0, 0);
    
        fft(x1, len, 1);
        fft(x2, len, 1);
        for (auto i = 0; i < len; i++)
            x1[i] = x1[i] * x2[i];
        fft(x1, len, -1);
        for (int i = 0; i < len; i++)
            sum[i] = static_cast<int>(lround(x1[i].real()));
        for (int i = 0; i < len; i++) {
            sum[i + 1] += sum[i] / 10;
            sum[i] %= 10;
        }
        len = len1 + len2 - 1;
        while (sum[len] <= 0 && len > 0)len--;
        for (int i = len; i >= 0; i--)
            cout << static_cast<char>(sum[i] + '0');
        cout << "
    ";
    
        return 0;
    }
    
  • 相关阅读:
    C# 基础知识系列- 11 委托和事件
    C# 基础知识系列- 10 反射和泛型(二)
    C# 基础知识系列- 9 字符串的更多用法(二)
    C# 基础知识系列- 9 字符串的更多用法(一)
    C# 基础知识系列- 8 Linq最后一部分查询表达式语法实践
    C# 基础知识系列- 6 Lambda表达式和Linq简单介绍
    C# 基础知识系列- 5 反射和泛型
    C# 基础知识系列- 4 面向对象
    TLS加密远程连接Docker
    树莓派4B安装64位Linux(不用显示器键盘鼠标)
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8185352.html
Copyright © 2011-2022 走看看