Skip to content

01019: Number Sequence

http://cs101.openjudge.cn/practice/01019/

cpp
#include <iostream>
using namespace std;

typedef long long ll;
class Solution
{
private:
    ll get_Sk_len(ll k)
    {
        ll len = 0;
        for (ll start = 1, digits = 1; start <= k; start *= 10, digits++)
        {
            ll end = start * 10 - 1;
            if (end > k)
                end = k;
            len += (end - start + 1) * digits;
        }
        return len;
    }

    ll get_total_len(ll k)
    {
        ll total = 0;
        for (ll start = 1, digits = 1; start <= k; start *= 10, digits++)
        {
            ll end = start * 10 - 1;
            if (end > k)
                end = k;

            ll first_Sk_len = get_Sk_len(start);
            ll last_Sk_len = get_Sk_len(end);
            ll n = (end - start + 1);

            total += (first_Sk_len + last_Sk_len) * n / 2;
        }
        return total;
    }

public:
    char solve(int x)
    {
        ll l = 1, r = 31268, k = 1;
        while (l <= r)
        {
            ll mid = l + (r - l) / 2;
            if (get_total_len(mid) >= x)
            {
                k = mid;
                r = mid - 1;
            }
            else
            {
                l = mid + 1;
            }
        }

        x -= get_total_len(k - 1);

        l = 1, r = k;
        ll num = 1;
        while (l <= r)
        {
            ll mid = l + (r - l) / 2;
            if (get_Sk_len(mid) >= x)
            {
                num = mid;
                r = mid - 1;
            }
            else
            {
                l = mid + 1;
            }
        }

        x -= get_Sk_len(num - 1);
        string s = to_string(num);
        return s[x - 1];
    }
};

int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    int t;
    cin >> t;
    Solution sol;
    while (t--)
    {
        ll x;
        cin >> x;
        cout << sol.solve(x) << '\n';
    }
    return 0;
}