Tək bölənlər#1520

Tək bölənlər (Həll təhlili)

Əgər ədədi təkdirsə, onda f(n) = n.

Əgər ədədi cütdürsə, onda f(n) = f(n / 2).

Güman edək ki,

g(n) = f(1) + f(2) + ... + f(n)

Təbii ədədlər çoxluğunu -dən -ə qədər iki altçoxluğa bölək:

-dən -ə qədər olan təbii ədədlər içərisində dəqiq olaraq:

O zaman:

f(1) + f(3) + f(5) + ... + f(2k - 1) = \\ 1 + 3 + 5 + … + (2k - 1) = \\ {1 +2k - 1\over 2} \cdot k = k^2

Eyni zamanda:

f(2) + f(4) + f(6) + ... + f(2l) = \\ f(1) + f(2) + f(3) + ... + f(l) = \\ g(l) = g(\left\lfloor n / 2 \right\rfloor)

Rekursiyanın bitməsini təmin edək ki, g(0) = 0. Beləliklə,

g(n) = \begin{cases} k^2 + g(\left\lfloor n / 2 \right\rfloor), k = (\left\lfloor n + 1) / 2 \right\rfloor \\ 0, n = 0 \end{cases}

Nümunə

İlk testi nəzərdən keçirək, harada n = 7.

-dən -ə qədər olan təbii ədədlər içərisində dəqiq olaraq:

g(7) = \left\lfloor 7 + 1 \over 2 \right\rfloor^2 + g\left(\left\lfloor 7 \over 2 \right\rfloor\right) = 16 + g(3) = \\ 16 + \left\lfloor 3 + 1 \over 2 \right\rfloor^2 + g\left(\left\lfloor 3 \over 2 \right\rfloor\right) = 16 + 4 + g(1) = 16 + 4 + 1 = 21

Alqoritmin realizasiyası

g funksiyasını reallaşdırırıq.

long long g(long long n)
{
  long long k = (n + 1) / 2;
  if (n == 0) return 0;
  return k * k + g(n / 2);
}

Proqramın əsas hissəsi. Hər bir test üçün giriş dəyəri -ı oxuyur və -ı çıxarır.

while(scanf("%lld",&n) == 1)
  printf("%lld\n",g(n));

Java realizasiyası

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 realizasiyası

g funksiyasını reallaşdırırıq.

def g(n):
  if n == 0:
    return 0
  k = (n + 1) // 2
  return k * k + g(n // 2)

Proqramın əsas hissəsi. Hər bir test üçün giriş dəyəri -ı oxuyur və -ı çıxarır.

for line in sys.stdin:
  n = int(line)
  print(g(n))