HDU 1402(A * B Problem Plus)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 50005;

__int64 G = 3, P = 469762049, wn[25];
char s1[N], s2[N];
__int64 a[3 * N], b[3 * N];

__int64 q_pow(__int64 a, __int64 b, __int64 M)
{
    __int64 ret = 1;
    a %= M;
    while (b)
    {
        if (b & 1)
            ret = ret * a % M;
        a = a * a % M;
        b >>= 1;
    }
    return ret;
}

void NTT(__int64 x[], int n, int rev)
{
    int i, j, k, s2, ds, id = 0;
    __int64 w, u, v;
    for (i = 1, j = n >> 1, k = n >> 1; i < n - 1; i++, k = n >> 1)
    {
        if (i < j)
            swap(x[i], x[j]);
        while (j >= k)
        {
            j -= k;
            k >>= 1;
        }
        if (j < k)
            j += k;
    }
    for (i = 2, ds = 1; i <= n; i <<= 1, ds++)
    {
        for (j = 0; j < n; j += i)
        {
            w = 1;
            for (k = j; k < j + i / 2; k++)
            {
                u = x[k] % P;
                v = w * x[k + i / 2] % P;
                x[k] = (u + v) % P;
                x[k + i / 2] = (u - v + P) % P;
                w = w * wn[ds] % P;
            }
        }
    }
    if (rev == -1)
    {
        for (i = 1; i < n / 2; i++)
            swap(x[i], x[n - i]);
        w = q_pow(n, P - 2, P);
        for (i = 0; i < n; i++)
            x[i] = x[i] * w % P;
    }
}

int main()
{
    for (int i = 0; i < 25; i++)
        wn[i] = q_pow(G, (P - 1) / (1 << i), P);
    while (cin >> s1 >> s2)
    {
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));

        int len1 = strlen(s1);
        int len2 = strlen(s2);
        int n = 1;
        while (n < len1 + len2)
            n <<= 1;

        for (int i = 0; i < len1; i++)
            a[i] = s1[len1 - i - 1] - '0';
        for (int i = 0; i < len2; i++)
            b[i] = s2[len2 - i - 1] - '0';

        NTT(a, n, 1);
        NTT(b, n, 1);

        for (int i = 0; i < n; i++)
            a[i] = a[i] * b[i] % P;

        NTT(a, n, -1);

        for (int i = 0; i < n - 1; i++)
            a[i + 1] += a[i] / 10, a[i] %= 10;
        while (a[n - 1] > 10)
        {
            a[n] += a[n - 1] / 10;
            a[n - 1] %= 10; n++;
        }
        while (n > 1 && !a[n - 1])
            n--;
        for (int i = n - 1; i >= 0; i--)
            cout << a[i];
        cout << endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值