For two given integers n and k find
(Zn + Zn-1
– 2Zn-2) mod
10000007,
where Zn = Sn + Pn,
Sn = 1k + 2k
+ 3k + ….. + nk and Pn = 11 + 22 + 33 + …… +
nn.
Input. There are several test cases. Each test case consists of one
line with two space separated positive integers n and k (1 < n < 2*108, 0 < k < 106). The last test
case contains two zeroes, which is not to be processed.
Output. For each case print the
asked value in separate line.
Sample
input |
Sample
output |
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);
}
Основная часть программы. Для каждой
пары чисел вычисляем сумму 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.io.*;
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);
}
}
}