Light oj 1132Summing up Powers (矩阵快速幂)

xiaoxiao2021-02-28  82

 

 

Given N and K, you have to find

(1K + 2K + 3K + ... + NK) % 232

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case contains two integers N (1 ≤ N ≤ 1015) and K (0 ≤ K ≤ 50) in a single line.

Output

For each case, print the case number and the result.

Sample Input

3

3 1

4 2

3 3

Sample Output

Case 1: 6

Case 2: 30

Case 3: 36

 

 

 

 

 

 

 

图源:点击打开链接

 

 

矩阵快速幂,D^(x - 1) * f(1) = f(x)

C(m,n)用杨辉三角的对应关系求得较为简单易得

D * f(x) = f(x + 1)

 

 

AC代码:

 

#include<algorithm> #include<iostream> #include<cstring> #include<stdio.h> #include<cmath> using namespace std; #define ll long long const ll mod = ((ll) 1 << 32); struct jz { ll m[55][55]; }f, d; ll N, K; ll C[55][55]; void yh() //利用杨辉三角值求C(m,n) { for(int i = 0; i <= 50; i++) { C[i][0] = 1; C[i][i] = 1; C[i][1] = i; } for(int i = 2; i <= 50; i++) { for(int j = 1; j <= i; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod; } } jz mul(jz A, jz B)//A*B { jz c; for(int i = 1; i <= K + 2; i++) { for(int k = 1; k <= K + 2; k++) { c.m[i][k] = 0; for(int j = 1; j <= K + 2; j++) c.m[i][k] = (c.m[i][k] + A.m[i][j] * B.m[j][k]) % mod; } } return c; } jz pow_(jz A, ll n) //A^n { jz ans = f; while(n) { if(n & 1) { n--; ans = mul(ans, A); } else { n /= 2; A = mul(A, A); } } return ans; } void D() { for(int i = 1; i <= K + 2; i++) { for(int j = 1; j <= K + 2; j++) { d.m[i][j] = 0; } } d.m[1][1] = 1; for(int i = 2; i <= K + 2; i++) d.m[1][i] = C[K][i - 2]; for(int i = 2; i <= K + 2; i++) { for(int j = i; j <= K + 2; j++) { d.m[i][j] = C[K - i + 2][j - i]; } } } void F() //f(1) { for(int i = 1; i <= K + 2; i++) { f.m[i][1] = 1; } } int main() { int T; cin>>T; yh(); for(int j = 1; j <= T; j++) { cin>>N>>K; F(); D(); jz flag = pow_(d, N - 1); jz ans = mul(flag, f); printf("Case %d: %lld\n", j, ans.m[1][1]); } return 0; }

 

 

转载请注明原文地址: https://www.6miu.com/read-84094.html

最新回复(0)