Квадрати і куби#10995

Квадрати і куби (Розбір)

Згенеруємо всі квадрати і куби натуральних чисел від до 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);
}