UVA - 10655 Contemplation! Algebra - 矩阵快速幂 , 构造辅助矩阵好题

传送门
一般肯定会想到取拆\((a + b)^n\)得到\(a^n + b^n\),但是得不到
就需要把\(f(n) = a^n + b^n\),然后去构造一个辅助方程直接得到结果
那么令\((a^n +b^n) (a + b) = a^(n + 1) + b^(n + 1) + ab^n + ba^n\)
那么就能得到\(f(n) = f(n - 1)p - f(n - 2)q\)
矩阵快速幂即可。
ps: cin才能过,以及注意n = 0,1,2时的特判即可

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int N = 2;
struct Matrix{
    int n, m;
    ll a[N][N];
    Matrix (int n = 0, int m = 0):n(n),m(m){memset(a, 0, sizeof(a));}
    Matrix operator * (const Matrix &b) const {
        Matrix ans(n, b.m);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                for(int k = 0; k < m; k++)
                    ans.a[i][j] += a[i][k] * b.a[k][j];
        return ans;
    }
};
Matrix ksm(Matrix a, ll b){
    Matrix ans(a.n, a.m);
    for(int i = 0; i < max(a.n, a.m); i++) ans.a[i][i] = 1;
    while(b) {
        if(b & 1) ans = ans * a;
        a = a * a;
        b >>= 1;
    }
    return ans;
}
int main(){
    ll p, q, n;
    while(cin >> p >> q >> n){
        if(n == 0) {
            printf("2\n");continue;
        } else if(n == 1) {
            printf("%lld\n", p);continue;
        }else if(n == 2) {
            printf("%lld\n", p * p - q * 2); continue;
        }
        Matrix base(2, 2);
        base.a[0][0] = p, base.a[0][1] = -q;
        base.a[1][0] = 1;
        base = ksm(base, n - 2);
        Matrix ans(2, 1);
        ans.a[0][0] = p * p - 2 * q;
        ans.a[1][0] = p;
        ans = base * ans;
        printf("%lld\n", ans.a[0][0]);
    }
    return 0;
}
posted @ 2020-10-13 08:47  Emcikem  阅读(81)  评论(0编辑  收藏  举报