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
| #include <iostream> #include <cmath> #include <algorithm> #include <vector> #define maxn 100010 #define sqtn 340 using namespace std;
const int p = 998244353; inline int add(int x, int y) { return (x += y) >= p ? x - p : x; } inline int mul(int x, int y) { return 1ll * x * y % p; } inline int add(initializer_list<int> lst) { int s = 0; for (auto t : lst) s = add(s, t); return s; }
int n, a[maxn];
struct Div_Hash { int id1[sqtn], id2[sqtn], w[sqtn * 2], sn, num, n; void init(int _n) { n = _n, sn = sqrt(n), num = 0; for (int l = 1, r; l <= n; l = r + 1) { r = n / (n / l), w[++num] = n / l; if (w[num] <= sn) id1[w[num]] = num; else id2[n / w[num]] = num; } } int get(int x) { return x <= sn ? id1[x] : id2[n / x]; } } _;
int f[2][sqtn * 2], g[2][sqtn * 2]; void work() { cin >> n; int ans = 0; for (int i = 1; i <= n; ++i) cin >> a[i]; _.init(a[n]), fill(f[n & 1], f[n & 1] + _.num + 1, 0), fill(g[n & 1], g[n & 1] + _.num + 1, 0); f[n & 1][_.get(a[n])] = 0, g[n & 1][_.get(a[n])] = 1; for (int i = n - 1, s = i & 1, t = s ^ 1; i; --i, swap(s, t)) { vector<pair<int, int>> lw; for (int j = 1; j <= _.num; ++j) lw.emplace_back(_.get(_.w[j]), _.w[j]); _.init(a[i]), fill(f[s], f[s] + _.num + 1, 0), fill(g[s], g[s] + _.num + 1, 0); f[s][_.get(a[i])] = 0, g[s][_.get(a[i])] = 1; for (auto [k, v] : lw) { int j = _.get(a[i] / ((a[i] + v - 1) / v)); f[s][j] = add({ f[s][j], f[t][k], mul(g[t][k], (a[i] + v - 1) / v - 1) }); g[s][j] = add(g[s][j], g[t][k]); } for (int j = 1; j <= _.num; ++j) ans = add(ans, f[s][j]); } cout << ans << "\n"; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int T; cin >> T; while (T--) work(); return 0; }
|