Create a complete binary tree containing numbers from 1 to n, for example. for n = 15, which will be:

In each branch, save the number of nodes to the left of it; this will allow us to quickly find the i-th node. (You will see that this tree has a very predictable structure and values, and its generation is much more efficient than creating a binary tree of the same size with random values. It is also an ideal candidate for a -an-array tree.)
Then, to find the ith number, start from the root of the node and on each node, if I am more than the number of nodes on the left, you find the i-th number number, else go left (if I am not more than the number of nodes to the left) or to the right ( if I have more than 1 more than the number of nodes on the left).
Whenever you go left, decrease the number of nodes to the left of this node (because we will delete it).
When you go right, decrease the number you are looking for by the number of nodes to the left of the node, plus 1 (or plus 0 if the value in the node has been erased).
When you find the i-th node, read its value (add to the list of removal order), and then set its value to 0. After that, if the i-th node is searched because its value is erased, we will go to the right and then take leftmost node.
We start with the value i = k, and then every time we erase the number in the ith node, we reduce the total number of nodes and set i = (i + k - 1) % total (or if it's zero: i = total ) .
This gives log 2 N search time and overall complexity of N x LogN.
An example of a pass: with n = 15 (as in the image above) and k = 6 , the first steps are 6, 12, 3, 10, 2. At this point, the situation is as follows:

We just deleted the second number, and now i = 2 + 6 - 1 = 7 . We start with the root of the node, which has 4 nodes to the left of it and still has its value, so we go to the right and subtract 5 from the 7 that we are looking for and get 2. We come to node 12 (which was deleted), and find there 2 nodes to the left of it, so we reduce the number of nodes to the left of it, and then go to the left. We come to node 10 (which was removed) and find that it has 1 node to its left, and 1 = 2 - 1, so this is the node we are looking for; however, since its value has been erased, we go right and subtract 1 from 2 that we are looking for and get 1. We arrive at node 11, which has 0 nodes to its left (because it is a leaf), and 0 = 1 - 1, so this is the node we are looking for.

Then we reduce the total number of nodes from 10 to 9 and I update from 7 to (7 + 6 - 1) % 9 = 3 and continue to search for the third node (which is now a value with a value of 5).
Here is a simple implementation in JavaScript. It solves a series of 100,000 numbers in less than a second, and it can probably be done faster and more economically using the tree structure in the array.
(Unlike the explanation above, the indexes of numbers are zero-based to simplify the code, so index 0 is the first number in the tree, and we are looking for a node with the number of left-bound children, which is equal to the target index.)
NOTE.
If you look at the tree for n = 10, you will see that the node to the right of the root has an incomplete tree with two nodes to the left, but the algorithm implemented in the code example above gives it an invalid left- node 3 instead of 2:

However, nodes with an incomplete tree to their left never matter on their own and never have nodes on their right. That way, you always go there, and the fact that their left node count is too big doesn't matter.