uva 10655 Algebraic Problem(矩阵快速幂)

  1. 已知:
     p = a + b;
     q = a * b;
 求:
     a^n + b^n

 构造矩阵:
     X(n) = a^n + b^n; 
     ……
     X(0) = 2;
     X(1) = a + b = p;

 X(n) = (a + b) * X(n-1) - a * b * X(n-2);
    
   | (a + b)  - a * b |     | X(n-1)|     |X(n)  |  
   |                  |  *  |       |  =  |      |
   |    1         0   |     | X(n-2)|     |X(n-1)|  


代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define ll unsigned long long

typedef struct
{
     ll m[2][2];
}Matrix;

Matrix A, B, per;
ll MOD;
void init(ll p, ll q)
{
     A.m[0][0] = p, A.m[1][0] = 2;

     B.m[0][0] = p, B.m[0][1] = q;
     B.m[1][0] = 1, B.m[1][1] = 0;

     per.m[0][0] = 1, per.m[0][1] = 0;
     per.m[1][0] = 0, per.m[1][1] = 1;

}

Matrix multi(Matrix a, Matrix b)
{
     Matrix c;
     for(int i = 0; i < 2; i ++)
     {
             for(int j = 0; j < 2; j ++)
             {
                     c.m[i][j] = 0;
                     for(int k = 0; k < 2; k ++)
                     {
                             c.m[i][j] = c.m[i][j] + (a.m[i][k] * b.m[k][j]) ;
                     }
                   
             }
     }
     return c;
}

Matrix Power(int k)
{
     Matrix ans = per, p = B;
     while(k)
     {
             if(k & 1) ans = multi(ans, p);
             k >>= 1;
             p = multi(p, p);
     }
     return ans;
}

ll  GetAns(Matrix a, Matrix b)
{
     ll ans = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] ;
     return ans;
}
int  main()
{
     int t;
     ll  p, q, n;
     scanf("%d", &t);
     for(int i = 1; i <= t; i ++)
     {
             scanf("%llu %llu %llu", &p, &q, &n);
             if(n == 0)
             {
                   printf("Case %d: 2\n", i);
                   continue;
             }
             init(p, -q);
             Matrix ans = Power(n-1);
             ll res = GetAns(ans, A);
             printf("Case %d: %llu\n", i, res);
     }
     return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值