码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵快速幂

时间:2018-10-30 17:48:26      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:scanf   turn   class   int   return   type   typedef   --   can   

斐波那切数列

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// 用二维vector来表示矩阵
typedef vector<ll> vec;
typedef vector<vec> mat;

// 模
const int M = 1000000007;

// 计算 A*B
mat mul(mat& A, mat& B) {
	mat C(A.size(), vec(B[0].size()));
	for ( int i = 0 ; i < A.size() ; ++ i ) {
		for ( int k = 0 ; k < B.size() ; ++ k ) {
			for ( int j = 0 ; j < B[0].size() ; ++ j ) {
				C[i][j] = (C[i][j]+A[i][k]*B[k][j]%M)%M;
			}
		}
	}
	return C;
}

// 计算 A^B
mat pow(mat A, ll n) {
	mat B(A.size(), vec(A.size()));
	for ( int i = 0 ; i < A.size() ; ++ i ) {
		B[i][i] = 1;
	}
	while ( n > 0 ) {
		if ( n & 1 ) B = mul(B, A);
		A = mul(A, A);
		n >>= 1;
	}
	return B;
}

int main()
{
    int T;
    scanf( "%d", &T );
    ll n;
    mat A(6, vec(6));
    while ( T -- ) {
        scanf( "%lld", &n);
        if ( n == 0 ) { puts( "0" ); continue; }
        if ( n == 1 ) { puts( "1" ); continue; }
        for ( int i = 0 ; i < 6 ; ++ i ) {
        	for ( int j = 0 ; j < 6 ; ++ j ) {
        		A[i][j] = 0;
        	}
        }
        A[0][0] = 1; A[0][1] = 1; A[0][2] = 1; A[0][3] = 4; A[0][4] = 6; A[0][5] = 4;
        A[1][0] = 1;
        A[2][2] = 1; A[2][3] = 3; A[2][4] = 3; A[2][5] = 1;
        A[3][3] = 1; A[3][4] = 2; A[3][5] = 1;
        A[4][4] = 1; A[4][5] = 1;
        A[5][5] = 1;
        A = pow(A, n-1);
        ll ans = 0;
        for ( int i = 0 ; i < 6 ; ++ i ) {
        	if ( i == 1 ) continue;
			ans = (ans+A[0][i])%M;
        }
		printf( "%lld\n", ans );
    }
    return 0;
}

  

矩阵快速幂

标签:scanf   turn   class   int   return   type   typedef   --   can   

原文地址:https://www.cnblogs.com/zlrrrr/p/9876611.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!