Создадим массив на 2N событий. Событие — эти тип («начало»/«конец»), № круга и координата. Каждый круг создаёт два события: начало на i−R и конец на i+R.
Массив сортируем по X, с таким уточнением, если X равны.
• Если касание считать пересечением, начало < конец (т.е. для точки X идут начала, затем концы). В такой ситуации нам не важны номера кругов.
• Если нет — сначала номера кругов (aka x-координаты центров) по возрастанию, затем начало < конец.
Заводим счётчик кругов. Проходимся по массиву.
• Если видим начало — к результату +счётчик, к счётчику +1.
• Если видим конец — к счётчику −1.
В нашем примере:
Счётчик 0, результат 0
Начало №1 на x=−4: результат 0, счётчик 1
Начало №0 на x=−1: результат 1, счётчик 2
Начало №2 на x=0: результат 3, счётчик 3
Начало №4 на x=0: результат 6, счётчик 4
Конец №0 на x=1: счётчик 3
Начало №3 на x=2: результат 9, счётчик 4
Затем аж два конца на x=4, счётчик опустился до 2
Начало №5 на x=5: результат 11, счётчик 3
Конец №5 на x=5: счётчик 2
И ещё два конца сбрасывают счётчик до 0.
UPD. Уточнил для случая, если касание — не пересечение.