zoukankan      html  css  js  c++  java
  • 高进度乘法FFT优化

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <set>
    #include <vector>
    using namespace std;
    #define L(x) (1 << (x))
    const double PI = acos(-1.0);
    const int Maxn = 133015;
    double ax[Maxn], ay[Maxn], bx[Maxn], by[Maxn];
    char sa[Maxn/2],sb[Maxn/2];
    int sum[Maxn];
    int x1[Maxn],x2[Maxn];
    int revv(int x, int bits)
    {
        int ret = 0;
        for (int i = 0; i < bits; i++)
        {
            ret <<= 1;
            ret |= x & 1;
            x >>= 1;
        }
        return ret;
    }
    void fft(double * a, double * b, int n, bool rev)
    {
        int bits = 0;
        while (1 << bits < n) ++bits;
        for (int i = 0; i < n; i++)
        {
            int j = revv(i, bits);
            if (i < j)
                swap(a[i], a[j]), swap(b[i], b[j]);
        }
        for (int len = 2; len <= n; len <<= 1)
        {
            int half = len >> 1;
            double wmx = cos(2 * PI / len), wmy = sin(2 * PI / len);
            if (rev) wmy = -wmy;
            for (int i = 0; i < n; i += len)
            {
                double wx = 1, wy = 0;
                for (int j = 0; j < half; j++)
                {
                    double cx = a[i + j], cy = b[i + j];
                    double dx = a[i + j + half], dy = b[i + j + half];
                    double ex = dx * wx - dy * wy, ey = dx * wy + dy * wx;
                    a[i + j] = cx + ex, b[i + j] = cy + ey;
                    a[i + j + half] = cx - ex, b[i + j + half] = cy - ey;
                    double wnx = wx * wmx - wy * wmy, wny = wx * wmy + wy * wmx;
                    wx = wnx, wy = wny;
                }
            }
        }
        if (rev)
        {
            for (int i = 0; i < n; i++)
                a[i] /= n, b[i] /= n;
        }
    }
    int solve(int a[],int na,int b[],int nb,int ans[])
    {
        int len = max(na, nb), ln;
        for(ln=0; L(ln)<len; ++ln);
        len=L(++ln);
        for (int i = 0; i < len ; ++i)
        {
            if (i >= na) ax[i] = 0, ay[i] =0;
            else ax[i] = a[i], ay[i] = 0;
        }
        fft(ax, ay, len, 0);
        for (int i = 0; i < len; ++i)
        {
            if (i >= nb) bx[i] = 0, by[i] = 0;
            else bx[i] = b[i], by[i] = 0;
        }
        fft(bx, by, len, 0);
        for (int i = 0; i < len; ++i)
        {
            double cx = ax[i] * bx[i] - ay[i] * by[i];
            double cy = ax[i] * by[i] + ay[i] * bx[i];
            ax[i] = cx, ay[i] = cy;
        }
        fft(ax, ay, len, 1);
        for (int i = 0; i < len; ++i)
            ans[i] = (int)(ax[i] + 0.5);
        return len;
    }
    string mul(string sa,string sb)
    {
        int l1,l2,l;
        int i;
        string ans;
        memset(sum, 0, sizeof(sum));
        l1 = sa.size();
        l2 = sb.size();
        for(i = 0; i < l1; i++)
            x1[i] = sa[l1 - i - 1]-'0';
        for(i = 0; i < l2; i++)
            x2[i] = sb[l2-i-1]-'0';
        l = solve(x1, l1, x2, l2, sum);
        for(i = 0; i<l || sum[i] >= 10; i++) // 进位
        {
            sum[i + 1] += sum[i] / 10;
            sum[i] %= 10;
        }
        l = i;
        while(sum[l] <= 0 && l>0)    l--; // 检索最高位
        for(i = l; i >= 0; i--)    ans+=sum[i] + '0'; // 倒序输出
        return ans;
    }
    int main()
    {
        cin.sync_with_stdio(false);
        string a,b;
        while(cin>>a>>b) cout<<mul(a,b)<<endl;
        return 0;
    }
    

  • 相关阅读:
    Flex 开源框架及工具 枫
    String.Format格式说明 枫
    HTTP服务器状态代码定义(Status Code Definitions) 枫
    像素对应表 枫
    js各种获取屏幕高度宽度 枫
    c#正则表达式帮助 枫
    使用模板引擎Trimpath 枫
    分布式缓存HttpRuntime.cache应用到单点登陆中_优化登陆 枫
    Query this 和 $(this) 的区别 枫
    css and js style 枫
  • 原文地址:https://www.cnblogs.com/Thereisnospon/p/4768457.html
Copyright © 2011-2022 走看看