Ceil Divisions (Codeforces 1469D)
Tags: Math, number theory

You have an array $$$a_1, a_2, \dots, a_n$$$ where $$$a_i = i$$$.In one step, you can choose two indices $$$x$$$ and $$$y$$$ ($$$x \neq y$$$) and set $$$a_x = \left\lceil \frac{a_x}{a_y} \right\rceil$$$ (ceiling function).Your goal is to make array $$$a$$$ consist of $$$n - 1$$$ ones and $$$1$$$ two in no more than $$$n + 5$$$ steps. Note that you don't have to minimize the number of steps.

Input: The first line contains a single integer $$$t$$$ ($$$1 \le t \le 1000$$$) — the number of test cases.The first and only line of each test case contains the single integer $$$n$$$ ($$$3 \le n \le 2 \cdot 10^5$$$) — the length of array $$$a$$$.It's guaranteed that the sum of $$$n$$$ over test cases doesn't exceed $$$2 \cdot 10^5$$$.

Output: For each test case, print the sequence of operations that will make $$$a$$$ as $$$n - 1$$$ ones and $$$1$$$ two in the following format: firstly, print one integer $$$m$$$ ($$$m \le n + 5$$$) — the number of operations; next print $$$m$$$ pairs of integers $$$x$$$ and $$$y$$$ ($$$1 \le x, y \le n$$$; $$$x \neq y$$$) ($$$x$$$ may be greater or less than $$$y$$$) — the indices of the corresponding operation.It can be proven that for the given constraints it's always possible to find a correct sequence of operations.

Note: In the first test case, you have array $$$a = [1, 2, 3]$$$. For example, you can do the following:   choose $$$3$$$, $$$2$$$: $$$a_3 = \left\lceil \frac{a_3}{a_2} \right\rceil = 2$$$ and array $$$a = [1, 2, 2]$$$;  choose $$$3$$$, $$$2$$$: $$$a_3 = \left\lceil \frac{2}{2} \right\rceil = 1$$$ and array $$$a = [1, 2, 1]$$$.  You've got array with $$$2$$$ ones and $$$1$$$ two in $$$2$$$ steps.In the second test case, $$$a = [1, 2, 3, 4]$$$. For example, you can do the following:   choose $$$3$$$, $$$4$$$: $$$a_3 = \left\lceil \frac{3}{4} \right\rceil = 1$$$ and array $$$a = [1, 2, 1, 4]$$$;  choose $$$4$$$, $$$2$$$: $$$a_4 = \left\lceil \frac{4}{2} \right\rceil = 2$$$ and array $$$a = [1, 2, 1, 2]$$$;  choose $$$4$$$, $$$2$$$: $$$a_4 = \left\lceil \frac{2}{2} \right\rceil = 1$$$ and array $$$a = [1, 2, 1, 1]$$$. 

Sample Inputs:
2
3
4

Sample Outputs:
2
3 2
3 2
3
3 4
4 2
4 2

Solution (Python):
from typing import List

def fun(n: int, R: List[str]):
    if n == 2:
        return
    x = n - 1
    while (n + x - 1) // x <= x:
        x -= 1
    x += 1
    for i in range(x + 1, n):
        R.append(f'{i} {i + 1}')
    R.append(f'{n} {x}')
    R.append(f'{n} {x}')
    fun(x, R)
for _ in range(int(input())):
    n = int(input())
    R = []
    fun(n, R)
    print(len(R))
    print('\n'.join(R))

Solution (Python):
from math import ceil
t = int(input())
for i in range(t):
    n = int(input())
    z = n
    res = []
    for j in range(n - 1, 2, -1):
        if ceil(z / j) >= j:
            res.append(str(n) + ' ' + str(j))
            z = ceil(z / j)
        res.append(str(j) + ' ' + str(n))
    while z > 2:
        z = ceil(z / 2)
        res.append(str(n) + ' 2')
    res.append('2 ' + str(n))
    print(len(res))
    print('\n'.join(res))

Solution (Python):
from sys import stdout
from math import ceil
t = int(input())
for i in range(t):
    n = int(input())
    if n <= 256:
        temp = n
        count = 0
        while temp > 1:
            count += 1
            temp = ceil(temp / 2)
        print(count + (n - 3))
        for i in range(3, n):
            stdout.write(str(i) + ' ' + str(n) + '\n')
        for i in range(count):
            stdout.write(str(n) + ' ' + str(2) + '\n')
    else:
        for i in range(0, 11):
            if pow(2, 2 * i) >= n:
                p1 = pow(2, i)
                break
        for i in range(0, 11):
            if pow(2, 2 * i) >= p1:
                p2 = pow(2, i)
                break
        temp = p2
        count = 0
        while temp > 1:
            count += 1
            temp = ceil(temp / 2)
        print(count + 4 + (n - 5))
        for i in range(3, n):
            if i != p1 and i != p2:
                stdout.write(str(i) + ' ' + str(n) + '\n')
        stdout.write(str(n) + ' ' + str(p1) + '\n')
        stdout.write(str(n) + ' ' + str(p1) + '\n')
        stdout.write(str(p1) + ' ' + str(p2) + '\n')
        stdout.write(str(p1) + ' ' + str(p2) + '\n')
        for i in range(count):
            stdout.write(str(p2) + ' ' + str(2) + '\n')