您的位置:首页 > 其它

hdu 5015 233 Matrix(矩阵快速幂)

2014-09-14 21:39 555 查看
题意:

给定一个n行m列的矩阵, 长成这样



从第一行第一列开始 a[i][j] = a[i-1][j-1] + a[i-1][j];

然后求 a
[m];

思路:

很明显, 设第i列的列向量为



m有点大, 同时n<=10, 可以考虑用矩阵快速幂加速, 但是递推的向量只有n维明显不是很行, 所以加两维, 变成



设上面中间的矩阵为A, 则 f[i] = A * f[i-1], f[m] = A ^ ( m - 1 ) * f[1];

先求出 f[1], 再用矩阵快速幂求出 f[m]

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

#define mxn 100020
#define mod 10000007
#define LL long long

int n, m;
int b[15][15];

void get_b() {
	memset( b, 0, sizeof( b ) );
	b[0][0] = 1;
	b[1][0] = 3, b[1][1] = 10;
	for( int i = 2; i <= n + 1; ++i ) {
		for( int j = 0; j <= n + 1; ++j )
			b[i][j] = b[i-1][j];
		b[i][i] = 1;
	}
}
struct mat {
	LL a[15][15];
	mat() {
		memset( a, 0, sizeof( a ) );
	}
	mat( int x ) {
		for( int i = 0; i <= n + 1; ++i )
			for( int j = 0; j <= n + 1; ++j )
				a[i][j] = b[i][j];
	}
	mat( int x, int y ) {
		memset( a, 0, sizeof( a ) );
		for( int i = 0; i <= n + 1; ++i )
			a[i][i] = 1;
	}
	mat operator * ( const mat& b ) const {
		mat ret;
		for( int i = 0; i <= n + 1; ++i )
			for( int j = 0; j <= n + 1; ++j )
				for( int k = 0; k <= n + 1; ++k )
					ret.a[i][j] = ( ret.a[i][j] + a[i][k] * b.a[k][j] ) % mod;
		return ret;
	}
};
mat qpow( mat t, int k ) {
	mat ret( 1, 1 );
	while( k ) {
		if( k & 1 )
			ret = ret * t;
		t = t * t;
		k >>= 1;
	}
	return ret;
}
LL a[30], c[30];
int main() {
	while( scanf( "%d%d", &n, &m ) != EOF ) {
		for( int i = 1; i <= n; ++i )
			scanf( "%d", &a[i] );
		get_b();
		mat t( 1 );
		t = qpow( t, m - 1 );
		c[0] = 1;
		c[1] = 233;
		for( int i = 2; i <= n + 1; ++i )
			c[i] = ( c[i-1] + a[i-1] ) % mod;
		LL ans = 0;
		for( int i = 0; i <= n + 1; ++i )
			ans = ( ans + c[i] * t.a[n+1][i] ) % mod;
		printf( "%I64d\n", ans );
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: