Fellow me on GitHub

LOJ1070(SummerTrainingDay05-B 矩阵快速幂)

Algebraic Problem

Given the value of a+b and ab you will have to find the value of an+bna and bnot necessarily have to be real numbers.

Input

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

Each case contains three non-negative integers, p, q and n. Here p denotes the value of a+b and q denotes the value of ab. Each number in the input file fits in a signed 32-bit integer. There will be no such input so that you have to find the value of 00.

Output

For each test case, print the case number and (an+bn) modulo 264.

Sample Input

2

10 16 2

7 12 3

Sample Output

Case 1: 68

Case 2: 91

 

令Sn =  an+bn  ,则有递推公式Sn = p×Sn-1 - q×Sn-2 ,构造矩阵[[p, 1], [-q, 0]],初始矩阵为[S1, S0]。

 1 //2017-08-05
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define ll unsigned long long 
 7 
 8 using namespace std;
 9 
10 ll p, q;
11 const int N = 10;
12 
13 struct Matrix{  
14     ll a[N][N];  
15     int r, c; 
16 }ori, res;  
17 
18 void init(){  
19     memset(res.a, 0, sizeof(res.a));  
20     res.r = 1; res.c = 2;
21     res.a[1][1] = p;
22     res.a[1][2] = 2;
23     ori.r = 2; ori.c = 2;//构造矩阵
24     ori.a[1][1] = p;
25     ori.a[1][2] = 1;
26     ori.a[2][1] = -q;  
27     ori.a[2][2] = 0;  
28 }
29 
30 Matrix multi(Matrix x, Matrix y)//矩阵乘法
31 {
32     Matrix z;
33     memset(z.a, 0, sizeof(z.a));  
34     z.r = x.r, z.c = y.c;
35     for(int i = 1; i <= x.r; i++){
36         for(int k = 1; k <= x.c; k++)//加速优化
37         {
38             if(x.a[i][k] == 0) continue;
39             for(int j = 1; j<= y.c; j++)
40                 z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]));
41         }
42     }
43     return z;
44 }
45 
46 void Matrix_pow(int n)//矩阵快速幂
47 {  
48     while(n){  
49         if(n & 1)  
50             res = multi(res, ori);  
51         ori = multi(ori, ori);  
52         n >>= 1;  
53     }  
54     printf("%llu\n", res.a[1][1]);  
55 }  
56 
57 
58 int main(){
59      int T, n;
60      scanf("%d", &T);
61      int kase = 0;
62      while(T--){
63         scanf("%lld%lld%d", &p, &q, &n);
64         init();
65         printf("Case %d: ", ++kase);
66         if(n == 0)printf("2\n");
67         else if(n == 1)printf("%llu\n", p);
68         else Matrix_pow(n-1);
69      }
70 
71     return 0;
72 }

 

posted @ 2017-08-05 21:45  Penn000  阅读(282)  评论(0编辑  收藏  举报