UVA 10655 - Contemplation! Algebra 矩阵快速幂

Given the value of a+b and ab you will have to find the value of a
n + b
n
Input
The input file contains several lines of inputs. Each line except the last line contains 3 non-negative
integers p, q and n. Here p denotes the value of a+b and q denotes the value of ab. Input is terminated
by a line containing only two zeroes. This line should not be processed. 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 line of input except the last one produce one line of output. This line contains the value of
a
n + b
n. You can always assume that a
n + b
n fits in a signed 64-bit integer.
Sample Input
10 16 2
7 12 3
0 0
Sample Output
68
91

 

题意: 

  给你三个非负整数,p,q,n,求a^n+b^n的值,其中a和b满足a+b=p,ab=q,注意a和b不一定是实数。

题解:

  设f(n)=an+bn,则有f(n)∗(a+b)=(an+bn)∗(a+b)=an+1+abn+ban+bn+1=f(n+1)+abf(n−1),

  所以f(n+1)=(a+b)f(n)−abf(n−1),用矩阵快速幂求解。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long ll;
const int  N = 100 + 10;
struct Mat {
    int r, l;
    ll arr[N][N];
    Mat (int r = 0, int l = 0) {
        sets(r, l);
        memset(arr, 0, sizeof(arr));
    }
    void sets (int r, int l) {
        this->r = r;
        this->l = l;
    }
    Mat operator * (const Mat& u) {
        Mat ret(r, u.l);
        for (int k = 0; k < l; k++) {
            for (int i = 0; i < r; i++)
                for (int j = 0; j < u.l; j++)
                    ret.arr[i][j] = (ret.arr[i][j] + arr[i][k] * u.arr[k][j]);
        }
        return ret;
    }
};
Mat pow_mat(Mat ans, Mat x, ll n) {
    while(n) {
        if(n&1) ans = x * ans;
        x = x * x;
        n >>= 1;
    }
    return ans;
}
int main() {
    ll n,p,q;
   while(scanf("%lld%lld%lld",&p,&q,&n) == 3 && p + q + n) {
    Mat ans(2,1);   
    ans.arr[0][0] = 2;
    ans.arr[1][0] = p;
    
    Mat x(2,2);
    x.arr[0][1] = 1;
    x.arr[1][0] = -q;
    x.arr[1][1] = p;
    if(n > 1) {
        ans = pow_mat(ans, x, n -1) ;
        printf("%lld\n",ans.arr[1][0]);
    }
    else printf("%lld\n", ans.arr[n][0]);
   }
    return 0;
}

 

posted @ 2016-01-24 21:33  meekyan  阅读(266)  评论(0编辑  收藏  举报