Для заданных
целых чисел 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();
}
}