《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; }