Якщо число непарне, то f(n) = n.
Якщо число парне, то f(n) = f(n / 2).
Нехай
Розглянемо розбиття множини натуральних чисел від до на два підмножини:
ODD — множина непарних чисел,
EVEN — множина парних чисел.
Серед натуральних чисел від до є рівно:
k = \left\lfloor (n + 1) / 2 \right\rfloor непарних
l = \left\lfloor n / 2 \right\rfloor парних чисел
Тоді:
В той же час:
Для завершення рекурсії покладемо g(0) = 0. Таким чином:
Приклад
Розглянемо перший тест, у якому n = 7.
Серед натуральних чисел від до є точно:
k = \left\lfloor (7 + 1) / 2 \right\rfloor = 4 непарних числа;
l = \left\lfloor 7 / 2 \right\rfloor = 3 парних числа.
Реалізація алгоритму
Реалізуємо функцію g.
long long g(long long n)
{
long long k = (n + 1) / 2;
if (n == 0) return 0;
return k * k + g(n / 2);
}Основна частина програми. Для кожного тесту читаємо вхідне значення та виводимо .
while(scanf("%lld",&n) == 1)
printf("%lld\n",g(n));Java реалізація
import java.util.*;
public class Main
{
static long g(long n)
{
long k = (n + 1) / 2;
if (n == 0) return 0;
return k * k + g(n / 2);
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
while(con.hasNext())
{
long n = con.nextLong();
System.out.println(g(n));
}
}
}Python реалізація
Реалізуємо функцію g.
def g(n):
if n == 0:
return 0
k = (n + 1) // 2
return k * k + g(n // 2)Основна частина програми. Для кожного тесту читаємо вхідне значення та виводимо .
for line in sys.stdin:
n = int(line)
print(g(n))