UVa 10655 Contemplation! Algebra 矩陣快速冪
阿新 • • 發佈:2017-07-31
names () linu algorithm turn nbsp typedef logs n-2
( a^(n-1) + b^(n-1) ) * ( a + b ) = a^n + a^(n-1) * b + a * b^(n-1) + b^n
a^n + b^n = p * ( a^(n-1) + b^(n-1) ) - q * ( a^(n-2) + b^(n-2) )
F(n) = p * F(n-1) - q * F(n-2)
Windows或C++用%lld和%llu
Linux或G++用%I64d和%I64u
#include <iostream> #include <cstdio> #include <cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 4; int msize; struct Mat { ll mat[N][N]; }; Mat operator *(Mat a, Mat b) { Mat c; memset(c.mat, 0, sizeof(c.mat)); for(int k = 0; k < msize; ++k) for(int i = 0; i < msize; ++i)if(a.mat[i][k]) for(int j = 0; j < msize; ++j) if(b.mat[k][j]) c.mat[i][j] = (a.mat[i][k] * b.mat[k][j] + c.mat[i][j]); return c; } Mat operator ^(Mat a, ll k) { Mat c; memset(c.mat,0,sizeof(c.mat)); for(int i = 0; i < msize; ++i) c.mat[i][i]=1; for(; k; k >>= 1) { if(k&1) c = c*a; a = a*a; } return c; } int main() { ll n,p,q; msize = 2; Mat A; while(scanf("%lld%lld%lld", &p, &q, &n) == 3) { if(n == 0) { puts("2"); continue; } A.mat[0][0] = p, A.mat[0][1] = -q; A.mat[1][0] = 1, A.mat[1][1] = 0; A = A^(n-1); printf("%lld\n", A.mat[0][0]*p + A.mat[0][1]*2); } return 0; }
UVa 10655 Contemplation! Algebra 矩陣快速冪