Power of Matrix UVA - 11149(矩陣倍增)

題目鏈接:點我


題意:

給你一個矩陣 A, 讓你求 A + A2 + A3 + A4 + A5 + …. An ,

思路:

矩陣倍增,那麼怎麼倍增呢, 令矩陣 S = A + A2 + A3 + A4 + A5 + … An = A + A2 + A3 + A4 + A5 + An/2 + An/2 * ( A + A2 + A3 + A4 + A5 + …. An/2 )
於是,我們這樣不斷的重複下去,就能算出答案了.

代碼:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

const int mod = 10;
int n,k;

struct mat{
    int a[42][42];
    mat(){memset(a, 0, sizeof(a)); }
    mat operator *(const mat q){
        mat c;
        for(int i = 1; i <= n; ++i)
            for(int  k = 1; k <= n; ++k)
            if(a[i][k])
        for(int j = 1; j <= n; ++j){
            c.a[i][j] += a[i][k] * q.a[k][j];
            if(c.a[i][j] >= mod)
                c.a[i][j] %= mod;
        }return c;
    }mat operator +(const mat q){
        mat c;
        for(int i = 1; i <= n;++i)
            for(int j = 1; j <= n; ++j)
            c.a[i][j] = (a[i][j] + q.a[i][j]) % mod;
        return c;
    }
};

mat qpow(mat x, int n){
    mat ans;
    for(int i = 1; i <= 40; ++i)
        ans.a[i][i] = 1;
    while(n){
        if(n&1) ans =ans * x;
        x = x * x;
        n >>= 1;
    }return ans;
}

mat solve(mat &x, int n){
    if(n == 1) return x;
    mat tmp = solve(x, n/2);
    mat sum = tmp * qpow(x,n/2)+ tmp;
    if(n&1) sum = sum + qpow(x,n);//如果n是奇數,那麼我們應該加上一項.
    return sum;
}

int main(){
    while(scanf("%d %d", &n, &k) != EOF&&n){
        mat ans;
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n ;++j)
                scanf("%d", &ans.a[i][j]),ans.a[i][j] %= 10;
        ans = solve(ans, k);
        for(int i = 1 ; i <= n ;++i){
            for(int j = 1; j < n ;++j)
                printf("%d ", ans.a[i][j]);
            printf("%d\n",ans.a[i][n]);
        }printf("\n");
    }return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章