[BZOJ2179] NTT快速傅立叶&高精度乘法

「BZOJ2179」

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
using namespace std;
const int mod=479*(1<<21)+1; 
const int N = 131100;
char s[N],t[N];
int n,m,l,r[N],c[N],a[N],b[N];
int power(int a,int b){int ans=1;for(;b;b>>=1,a=1LL*a*a%mod)if(b&1)ans=1LL*ans*a%mod;return ans;}
 
void ntt(int *a, int f) {
    for(int i = 0; i < n; i++) if(r[i] > i) swap(a[i], a[r[i]]);//attention
    for(int i = 1; i <n; i <<= 1) {
        int wn=power(3,(mod-1)/(i*2));
        if(f==-1)wn=power(wn,mod-2);
        for(int j = 0; j < n; j += (i<<1)) {
            int w = 1;
            for(int k = 0; k < i; k++, w =1LL*w* wn%mod) {
                int x = a[j+k], y = 1LL*w*a[j+k+i]%mod;//attention
                a[j+k] = x+y, a[j+k+i] = x-y;
                a[j+k]=(a[j+k]%mod+mod)%mod;
                a[j+k+i]=(a[j+k+i]%mod+mod)%mod;
            }
        }
    }
    if(f==-1)//attention
    {
        int rev=power(n,mod-2);
        rep(i,0,n-1) a[i]=((ll)a[i]*rev)%mod;
    }
}
int main() {
    scanf("%d%s%s", &m, s, t);
    for(int i = 0; i < m; i++) a[i] = s[m-i-1]-'0', b[i] = t[m-i-1]-'0';
    for(n = 1, m <<= 1; n < m; n <<= 1) l++;
    for(int i = 0; i < n; i++) r[i] = (r[i>>1]>>1)|((i&1)<<(l-1));
    ntt(a, 1), ntt(b, 1);
    for(int i = 0; i < n; i++) a[i]=1LL*a[i]* b[i]%mod;
    ntt(a, -1);
    for(int i = 0; i <=m; i++) if(a[i] >= 10) {
        a[i+1] += a[i]/10, a[i] %= 10;
        if(i==m)m++;
    }while(!a[m]) m--;
    for(int i = m; i>=0; i--) printf("%d", a[i]);
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值