5493. Просто просуммируйте

 

Для заданных целых чисел n и k найдите

(Zn + Zn-1 – 2Zn-2) mod 10000007,

где Zn = Sn + Pn, Sn = 1k + 2k + 3k + ….. + nk и Pn = 11 + 22 + 33 + …… + nn.

 

Вход. Состоит из нескольких тестов. Каждый тест состоит из одной строки, содержащей два положительных целых числа n и k (1 < n < 2*108,  0 < k < 106). Последний тест содержит два нуля и не обрабатывается.

 

Выход. Для каждого теста выведите ответ в отдельной строке.

 

Пример входа

Пример выхода

10 3

9 31

83 17

5 2

0 0

4835897

2118762

2285275

3694

 

 

РЕШЕНИЕ

математика + рекурсия

 

Анализ алгоритма

Упростим требуемое выражение:

Zn + Zn-1 – 2Zn-2 = Sn + Sn-1 – 2 * Sn-2 + Pn  + Pn-1 – 2* Pn-2  =

(1k + 2k + 3k + ….. + nk) + (1k + 2k + 3k + ….. + (n – 1)k) –

2*(1k + 2k + 3k + ….. + (n – 2)k) + (11 + 22 + 33 + …… + nn) +

(11 + 22 + 33 + …… + (n – 1)n-1) –  2*(11 + 22 + 33 + …… + (n – 2)n-2) =

= nk + 2(n – 1)k + nn + 2(n – 1)n-1

Остается вычислить сумму четырех слагаемых, взятую по модулю 10000007.

 

Реализация алгоритма

Объявим константу MOD, равную 10000007.

 

#define MOD 10000007

 

Функция PowMod возвращает значение xn mod MOD .

 

long long PowMod(long long x, long long n)

{

  if (!n) return 1;

  if (n & 1) return (x * PowMod((x * x) % MOD, n / 2)) % MOD;

  return PowMod((x * x) % MOD, n / 2);

}

 

Основная часть программы. Для каждой пары чисел n и k вычисляем сумму nk + 2(n – 1)k + nn + 2(n – 1)n-1 по модулю MOD.

 

while(scanf("%lld %lld",&n,&k), n + k)

{

  res = (PowMod(n,k) + 2*PowMod(n-1,k) + PowMod(n,n) +

                       2*PowMod(n-1,n-1)) % MOD;

  printf("%d\n",res);

}

 

Java реализация

 

import java.util.*;

 

public class Main

{

  private final static long MOD = 10000007;   

  static long PowMod(long x, long n)

  {

    if (n == 0) return 1;

    if (n % 2 == 1) return (x * PowMod((x * x) % MOD, n / 2)) % MOD;

    return PowMod((x * x)% MOD, n / 2);

  }

   

  public static void main(String[] args)

  {

    Scanner con = new Scanner(System.in);

    while(true)

    {

      long n = con.nextLong();

      long k = con.nextLong();

      if (n + k == 0) break;

      long res = (PowMod(n,k) + 2*PowMod(n-1,k) +

                  PowMod(n,n) + 2*PowMod(n-1,n-1)) % MOD;

      System.out.println(res);

    }

    con.close();

  }

}