Згенеруємо всі квадрати і куби натуральних чисел від до 10^9 і збережемо їх у множину . Повторювані числа автоматично виключаються, оскільки множина не допускає дублікатів. Потім скопіюємо елементи множини в масив , який вже буде відсортований за зростанням, тому що — впорядкована множина.
Далі для кожного вхідного числа за допомогою бінарного пошуку визначимо кількість квадратів і кубів, що не перевищують . Для цього використовуємо пошук за верхньою межею (upper\_bound) — він поверне позицію першого елемента в масиві , строго більшого . Ця позиція і буде відповіддю на запит, оскільки вона відповідає кількості підходящих чисел.
Приклад
Згенеруємо квадрати і куби чисел від до включно.
Виконаємо запит для n = 30. У цьому випадку знайдена позиція буде рівна pos = 7, тобто в інтервалі від до містяться рівно підходящих чисел. Нагадаємо, що індексація в масиві починається з нуля.
Реалізація алгоритму
Згенеруємо всі квадрати і куби натуральних чисел від до 10^9 і збережемо їх у множину . Якщо число одночасно є квадратом і кубом (наприклад, ), воно буде додане в множину лише один раз, оскільки множини автоматично виключають повтори.
for (i = 1; i * i <= 1000000000; i++)
s.insert(i * i);
for (i = 1; i * i * i <= 1000000000; i++)
s.insert(i * i * i);Потім перенесемо елементи множини в масив . Оскільки множина впорядкована, масив також буде відсортований за зростанням.
v = vector<int>(s.begin(), s.end());Послідовно обробляємо тестів.
scanf("%d", &tests);
while (tests--)
{
scanf("%d", &n);За допомогою бінарного пошуку за верхньою межею знаходимо найменший індекс такий, що всі квадрати і куби натуральних чисел, не перевищуючі , знаходяться в масиві на позиціях від до pos - 1. Таким чином, кількість виписаних чисел від до дорівнює .
res = upper_bound(v.begin(), v.end(), n) - v.begin();
printf("%d\n", res);
}