Explanation
Note that this is very tricky for a bronze problem!
Since can be as big as , there is no way we can approach this problem through brute force. Instead, we'll need to work out an algorithm that can answer queries in logarithmic time.
Let's group numbers by how many digits they have. An observation we can make is that for any , there are numbers in the group with numbers of length . Additionally, for each group, the total count of digits from all of the group's numbers combined is times how many numbers are in the group. For instance:
- Length numbers: numbers digits total
- Length numbers: numbers digits total
- Length numbers: numbers digits total
- And so on...
To find which group the number that contains the th digit is in, we can iterate through groups until the sum of the total number of digits from all the groups we've processed becomes greater than or equal to . In other words, we continue increasing the number of groups we look at (starting from -digit numbers) until the following is true:
Once the condition becomes true, we know that the th digit must fall into the last group used in the sum. We can now calculate the th digit's position in the group by subtracting by the total number of digits from all groups before it. We'll call this relative position :
Note that we subtract from the result in order to make -based (which makes it more convenient to solve the rest of the problem). For example, if , that would mean the th digit is the first digit in the group. If , that would mean the th digit is the -th digit in the group, etc. From there, we can divide by (the length of the numbers in the group), which gives us the position of the number that contains the th digit within the group (also -based). Similarly as before, a position of means that the number is the first number in the group, and a position of means that the number is the -th number in the group.
To calculate the exact number the th digit is in, we can add the position of the number within the group (which we just found) to the value of the first number of the group, which is just (you can find this pattern from the beginning example). Now, all that's left is finding the position of the -th digit within the number that it's in. We can calculate that by taking , which finds the remainder of when divided by . For example, let's look at the first digits in the group with length numbers:
| Digit Sequence | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Position |
As you can see, for each -digit number in the digit sequence, the first digit is always at a position that's a multiple of , meaning the position modulo equals . Similarly, the second digit in each number is always at a position that's plus a multiple of , meaning its position modulo equals . Finally, the third digit in each number is always plus a multiple of , meaning that its position modulo equals . This pattern extends for numbers of all sizes, and it is thus why we can use the modulo operator to determine the th digit's -based position within the number it's inside.
Now, we can calculate our answer by converting the number that the th digit is in into a string and indexing it at the position we've just found.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;typedef long long ll;// Returns 10 to the power of "exp"// Not using pow() because it can be inaccurate for large powersll pow10(int exp) {ll product = 1;for (int i = 0; i < exp; i++) { product *= 10; }return product;
Java
import java.io.*;import java.util.*;public class DigitQueries {public static void main(String[] args) {Kattio io = new Kattio();int q = io.nextInt();for (int i = 0; i < q; i++) {long k = io.nextLong();
Python
for _ in range(int(input())):k = int(input())"""Subtract k by sizes of groups until k becomes smaller than the size of thecurrent group. This produces the same effect as summing group sizes untilk becomes less than or equal to the sum. By the time the while loop ends,k - 1 will equal j."""n = 1while k > n * 9 * 10 ** (n - 1):
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!