题目链接:点我
题意:
给你a + b 和 a * b 让你计算 $ a ^{n}$ + $ b ^{n}$
思路:
矩阵快速幂.
刚开始看见这个式子我也是懵逼的,后来就想,看看能不能找规律,于是自己手写了几项, 发现还是真的有一部份规律. $ a^{n}$ + bn =($ a^{n - 1}$ + bn−1) * ( a + b - a * b ) ,突然发现自己乱写乱画也弄出个公式(高兴), 于是愉快的A 了这题.
递推矩阵 😒 \begin {pmatrix} q & -p\ 1 & 0\ \end{pmatrix}$
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std;
typedef long long LL;
struct mat{ LL a[10][10]; mat(){memset(a, 0, sizeof(a)); } mat operator *( const mat q){ mat c; for(int i = 1; i <= 2;++i) for(int k = 1; k<= 2; ++k) for(int j =1; j<= 2; ++j) c.a[i][j] += a[i][k] * q.a[k][j]; return c; } };
mat qpow(mat x,LL n){ mat ans; ans.a[1][1] = ans.a[2][2] = 1; while(n){ if(n&1) ans =ans * x; x =x * x; n >>= 1; }return ans; }
int main(){ LL p, q, n; while(scanf("%lld %lld %lld", &q, &p, &n) == 3){ if(n == 0){ printf("2\n"); continue; }else if(n == 1){ printf("%lld\n",q); continue; } else if(n == 2){ printf("%lld\n",q*q - 2*p); continue; }mat ans; ans.a[1][1] = q; ans.a[1][2] = -p; ans.a[2][1] = 1; ans = qpow(ans,n-2); LL sum1 = q; LL sum2 = q*q - 2 * p; LL sum = sum1 * ans.a[1][2] + sum2 * ans.a[1][1]; printf("%lld\n",sum); }return 0; }
|