1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| #include <bits/stdc++.h> using namespace std; const int N = (1 << 19) | 5,P = 998244353; inline int Add(const int &a,const int &b) { return (a + b >= P) ? (a + b - P) : (a + b);} inline int Sub(const int &a,const int &b) { return (a < b) ? (a - b + P) : (a - b);} inline int qpow(int a,int b) { int res = 1;while(b) { if(b&1) res = 1ll * res * a % P;a = 1ll * a * a % P;b >>= 1;} return res;} inline void Plus(int &x,const int &y) { x += y;if(x >= P) x -= P;} const int G = 3,Gi = qpow(G,P - 2); int rev[N]; inline void calc_rev(int len) { for(int i = 0;i < len;i++) { rev[i] = rev[i >> 1] >> 1; if(i & 1) rev[i] |= len >> 1; } } int Gs[N],Gs2[N]; inline int GetLen(int x) { int len = 1; while(len <= x) len <<= 1; return len; } inline void initG(int len) { for(int i = 1;i < len;i <<= 1) { Gs[i] = Gs2[i] = 1; Gs[i + 1] = qpow(G,(P - 1) / (i << 1)); Gs2[i + 1] = qpow(Gi,(P - 1) / (i << 1)); for(int j = 2;j < i;j++) Gs[i + j] = 1ll * Gs[i + j - 1] * Gs[i + 1] % P, Gs2[i + j] = 1ll * Gs2[i + j - 1] * Gs2[i + 1] % P; } } inline void FFT(int *F,int len,int type) { for(int i = 0;i < len;i++) if(i < rev[i]) swap(F[i],F[rev[i]]); for(int k = 1;k < len;k <<= 1) for(int j = 0;j < len;j += k + k) for(int i = 0;i < k;i++) { int cur = type == 1 ? Gs[k | i] : Gs2[k | i]; int u = F[i | j],v = 1ll * cur * F[i | j | k] % P; F[i | j] = Add(u,v); F[i | j | k] = Sub(u,v); } if(type == -1) for(int i = 0,Inv = qpow(len,P - 2);i < len;i++) F[i] = 1ll * F[i] * Inv % P; }
int n,fac[N],inv[N],ifac[N]; inline void init(int n) { fac[0] = 1; for(int i = 1;i <= n;i++) fac[i] = 1ll * fac[i - 1] * i % P; inv[1] = 1; for(int i = 2;i <= n;i++) inv[i] = 1ll * (P - P / i) * inv[P % i] % P; ifac[0] = 1; for(int i = 1;i <= n;i++) ifac[i] = 1ll * ifac[i - 1] * inv[i] % P; } inline int C(int n,int m) { if(n < 0 || m < 0 || n < m) return 0;return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;} char s[N]; int tf[N],tg[N],ans[N]; int main() { scanf("%s",s + 1); n = strlen(s + 1); initG(1 << 19); init(n); int lim = n; for(int i = 1;i < n;i++) if(s[i] > s[i + 1]) {lim = i;break;} for(int i = 1;i <= lim;i++) ans[i] = 1; int len = GetLen(n + n + 2); calc_rev(len); for(int c = '9';c >= '1';c--) { int tl,tr,ct; tl = tr = ct = -1; for(int i = 1;i <= n;i++) if(s[i] == c) { tl = i;break;} if(tl == -1 || tl > lim) continue; tr = tl;while(tr < n && s[tr + 1] == c) ++tr; ct = tr + 1; while(ct <= n && s[ct] > c) ++ct;
for(int i = 0;i < len;i++) tf[i] = tg[i] = 0; for(int i = tr;i < ct;i++) tf[i] = ans[i]; for(int i = 0;i < ct - tr;i++) tg[i] = C(tr - tl + i,i); FFT(tf,len,1);FFT(tg,len,1); for(int i = 0;i < len;i++) tf[i] = 1ll * tf[i] * tg[i] % P; FFT(tf,len,-1); for(int i = tr;i < ct;i++) ans[i] = tf[i]; for(int i = tl;i < tr;i++) ans[i] = 1; } cout << ans[n] << endl; return 0; }
|