If we want to know what digit is on specified position, we need to locate the $S_{S_n}$ which contains what we want, and further need to locate the $S_m$ in $S_{S_n}$ which contains what we want, and finally the $k$ in $S_m$. As a result, we need the length of $S_{S_k}$ and the length of $S_k$.
$$|S_k|=\sum_{1 \leq l \leq k}{l \times \text{Counts of number with $l$ digits}}$$
$$|S_{S_k}|=\sum_{1 \leq l \leq k}{|S_l|}$$
We can firstly calculate some of $|S_k|$, and then the $|S_{S_k}|$ until the maximum value less than INT_MAX. We can use this predication to examine the overflow of add operator: sum + k < sum. As the arrays containing $|S_k|$ and $|S_{S_k}|$ are naturally sorted, we can use binary search to improve the performance. Finally, we just need to know the digit in specified position of a number $k$. It’s a easy job and can be approached by converting $k$ into string and seek its specified position.
Solution
After some experiences, I know only first 31267 of $|S_{S_k}|$ need to be calculated.
constint MaxK = 31267; int LengthOfSkTable[MaxK + 1] = { 0 }; int LengthOfSSkTable[MaxK + 1] = { 0 };
intGetNumberBits(int number) { int bits = 0; for(; number; number /= 10) { bits++; } return bits; }
intLengthOfSk(int k) { int bits = GetNumberBits(k); int sum = 0; for (int i = 1; i < bits; i++) { sum += i * MaxNumberCountByBit[i]; } sum += (k - MinNumberByBit[bits] + 1) * bits; return sum; }
voidInitialize(void) { for (int k = 1, sum = 0; k <= MaxK; k++) { int l = LengthOfSk(k); LengthOfSkTable[k] = l; LengthOfSSkTable[k] = (sum += l); } }
intSolve(int position) { int *previousSSkLengthIt = lower_bound(&LengthOfSSkTable[1], &LengthOfSSkTable[MaxK + 1], position) - 1; int positionInSk = position - *previousSSkLengthIt;
int *previousSkLengthIt = lower_bound(&LengthOfSkTable[1], &LengthOfSkTable[MaxK + 1], positionInSk) - 1; int positionInKK = positionInSk - *previousSkLengthIt; int kk = distance(&LengthOfSkTable[0], previousSkLengthIt) + 1;
stringstream ss; ss << kk; char number = ss.str().at(positionInKK - 1);
return number - '0'; }
intmain(void) { Initialize();
int t; cin >> t; while (t--) { int i; cin >> i; cout << Solve(i) << endl; }