GYM101845A:Apple Trees矩阵快速幂

GYM101845A

题解

  • f(i,j)表示第i年年龄为j的树有多少。
  • f(n,0)=16f(n-1,9)+9f(n-1,19)+4f(n-1,29)+1f(n-1,39)
  • f(n,i)=f(n-1,i-1)

代码

#include <bits/stdc++.h>
using namespace std;
int const MOD = 1e9 + 7;
typedef long long ll;
int const N = 50;
int const size = 45;
ll n;
struct mat{
	ll m[N][N];
}a,init;
mat operator * (mat a,mat b){
	mat ans;
	for(int i=0;i<size;i++){
		for(int j=0;j<size;j++){
			ans.m[i][j] = 0;
			for(int k=0;k<size;k++)
				ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
		}
	}
	return ans;
}
void build(){
	a.m[0][9] = 16,	a.m[0][19] = 9,	a.m[0][29] = 4,	a.m[0][39] = 1;
	for(int i=1;i<size;i++)	a.m[i][i-1] = 1;
	for(int i=0;i<size;i++)	init.m[i][i] = 1;
}
mat quick_pow(mat a,ll n){
	mat ans = init;
	while(n){
		if(n&1)	ans = ans * a;
		a = a * a;
		n >>= 1;
	}
	return ans;
}
int main(){
	scanf("%lld",&n);
	build();
	mat ans = quick_pow(a,n);
	ll res = 0;
	for(int i=0;i<size;i++)
		res = res + ans.m[i][0];
	printf("%lld\n",res % MOD);
	return 0;
}

 

posted @ 2019-05-20 09:40  月光下の魔术师  阅读(22)  评论(0)    收藏  举报