《HDU 1402》

究极折磨折磨。

这题一开始数组开小了导致一直TLE。。

数组大小其实应该开4倍比较稳。

这里很重要的一点就是,这里其实NTT和FTT复杂度都挺够的。

我们看成x = 10的多项式就行了。

但是这里有两个坑,首先,卷积之后的多项式系数可能是多位数,但是答案需要转化成10进制乘积来输出,所以就需要进行进位操作了。

然后这里的输入可能有前缀0。。所以最后输出需要舍掉不合法的前缀0.

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> pii;
const int N = 1e5 + 5;
const int M = 1e5 + 5;
const LL Mod = 199999;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;

int limit = 1,n,m,r[N << 1];
char s1[N],s2[N];
LL a[N << 1],b[N << 1],P = 998244353,G = 3,Gi = 332748118;
LL quick_mi(LL a,LL b) {
    LL re = 1;
    while(b) {
        if(b & 1) re = re * a % P;
        b >>= 1;
        a = a * a % P;
    }
    return re;
}
void NTT(LL *a,int id) {
    for(int i = 0;i < limit;++i) {
        if(i < r[i]) swap(a[i],a[r[i]]);
    }
    for(int i = 1;i < limit;i <<= 1) {
        LL wn = quick_mi(id == 1 ? G : Gi,(P - 1) / (i << 1));
        for(int j = 0;j < limit;j += (i << 1)) {
            LL w = 1;
            for(int k = 0;k < i;++k,w = (w * wn) % P) {
                LL p = a[j + k],q = w * a[j + k + i] % P;
                a[j + k] = (p + q) % P;
                a[j + k + i] = (p - q + P) % P;
            }
        }
    }
}
//n次多项式,有n + 1项
int main() {
    while(~scanf("%s %s",s1,s2)) {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(r,0,sizeof(r));
        limit = 1;
        n = strlen(s1) - 1,m = strlen(s2) - 1;
        for(int i = 0;i <= n;++i) {
            LL x = (s1[n - i] - '0');
            a[i] = (x + P) % P;
        }
        for(int i = 0;i <= m;++i) {
            LL x = (s2[m - i] - '0');
            b[i] = (x + P) % P;
        }
        int L = 0;
        while(limit <= (n + m)) limit <<= 1,++L;
        for(int i = 0;i < limit;++i) {
            r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
        }
        NTT(a,1);
        NTT(b,1);
        for(int i = 0;i <= limit;++i) a[i] = (a[i] * b[i]) % P;
        NTT(a,-1);
        for(int i = n + m;i >= 0;--i) a[i] = a[i] * quick_mi(limit,P - 2) % P;
        int len = n + m;
        for(int i = 0;i <= len;++i) {
            a[i + 1] += a[i] / 10;
            a[i] %= 10;
        }
        int f = 0;
        if(a[len + 1] != 0) ++len;
        for(int i = len;i >= 0;--i) {
            if(a[i] == 0) {
                if(i == 0 || f != 0) printf("%lld",a[i]);
            }
            else {
                f = 1;
                printf("%lld",a[i]);
            }
        }
        printf("\n");
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-05-18 11:01  levill  阅读(41)  评论(0编辑  收藏  举报