#nullable enable #region var (_input, _iter) = (Array.Empty(), 0); T I() where T : IParsable { while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Trim().Split(' '), 0); return T.Parse(_input[_iter++], null); } #endregion const long Mod = 7000000001; var ns = I(); // var n = int.Parse(new string([..ns.Reverse()])); var n = int.Parse(ns); var tens = new long[20]; tens[0] = 1; for (var i = 1; i < 20; i++) tens[i] = tens[i - 1] * 10; var f = new Dictionary[20, 2]; (long, long) F(long x, int j, bool z) { if (j == 0 && x < 10) return (x * (x + 1) / 2, x + 1); var zn = z ? 1 : 0; if (f[j, zn].TryGetValue(x, out var cv)) return cv; long v = 0; long c = 0; var ten = tens[j]; var d = x / ten; if (d > 0) { var (nv, nc) = F(ten - 1, j - 1, z); if (z) v += nv * 10; else v += nv; c += nc; } if (d > 1) { var (nv, nc) = F(ten - 1, j - 1, true); v += nv * 10 * (d - 1) + nc * d * (d - 1) / 2; c += nc * (d - 1); } { var nz = z || d > 0; var (nv, nc) = F(x - ten * d, j - 1, nz); if (nz) v += nv * 10 + nc * d; else v += nv; c += nc; } var res = (v % Mod, c % Mod); f[j, zn][x] = res; return res; } int T(long x) { var res = 0; while (x >= 10) (x, res) = (x / 10, res + 1); return res; } var ans = new List(); for (var lp = 0; lp < n; lp++) { for (var i = 0; i < 20; i++) { f[i, 0] = new(); f[i, 1] = new(); } var ls = I(); var rs = I(); // var l = long.Parse(new string([..ls.Reverse()])); // var r = long.Parse(new string([..rs.Reverse()])); var l = long.Parse(ls); var r = long.Parse(rs); var t = T(r); var rns = F(r, t, false).Item1; var lns = F(l - 1, t, false).Item1; var qns = (rns - lns + Mod) % Mod; // var sns = new string([..qns.ToString().Reverse()]); var sns = qns.ToString(); ans.Add(long.Parse(sns)); // var dbg = 0L; // for (var j = 0; j <= r; j++) // { // var rev = j.ToString().Reverse(); // dbg += long.Parse(new string([..rev])); // } // Console.WriteLine(dbg); } Console.WriteLine(string.Join(Environment.NewLine, ans));