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; }