#include #include #include #include using i64 = long long; using namespace std; #include using Modint = atcoder::static_modint<998244353>; using Modint2 = atcoder::static_modint<998244352>; // a**2**x Modint powpow2( Modint a, i64 x ){ if(a.val() == 0) return 1; i64 idx = (Modint2(2).pow(x) - 1).val(); return a.pow(idx) * a; } // (a**2**x - 1) / (a - 1) Modint geometric( Modint a, i64 x ){ if(a.val() == 0) return 1; if(a.val() == 1) return Modint(2).pow(x); return (powpow2(a,x) - 1) / (a - 1); } // freq count a**2**k ( 0 <= k < n ) vector> counter(Modint a, i64 n){ vector f; f.push_back(a); i64 cybeg = -1; for(i64 t=1; t> res; for(i64 i=0; i<(i64)f.size(); i++){ res.push_back({ f[i], 1 }); } if(cybeg != -1){ i64 n2 = n - f.size(); i64 cylen = f.size() - cybeg; for(i64 k=0; k sub2( i64 len, Modint n, Modint interval ){ if(len == 1){ return { n, interval }; } n -= 1; auto base = counter(interval, len); Modint ans = geometric(interval, len) * n; Modint ointerval = powpow2(interval, len); Modint t = powpow2(interval, len) - 1; for(auto [u,v] : base){ if(u.val() != 1){ ans += t / (u - 1) * v; } else { ans += ointerval * v; } } ans -= n; ans -= len; ans /= interval; ointerval /= interval; return { ans, ointerval }; } pair sub( i64 len, Modint n, Modint val, Modint interval1, Modint interval2 ){ auto [u,v] = sub2(len, val * interval2 + n, interval1 * interval2); return { u * interval1 + val, v * interval1 }; } Modint naive( i64 n ){ Modint ans = 0; Modint k = 1; for(i64 i=1; i<=n; i++){ i64 len = to_string(i).size(); Modint j = Modint(10).pow(len); ans = ans * j * k + Modint(i) * k + ans; k = k * j * k; } return ans; } void testcase(){ i64 n; cin >> n; i64 dig = 1; i64 m = 1; while(m <= n/10){ dig += 1; m *= 10; } vector>> A; for(i64 k=1; k