CF1117D Magic Gems

原本我是枚举这个转换的个数(x),然后就是一个组合数求和的形式,我以为是什么高端东西,所以就不会了。

考虑设计 (f_i)(i) 的方案数。
那么有 (f_i = f_{i - 1} + f_{i - m})
那么直接矩阵加速吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long 
#define N 205
#define mod (ll)(1e9 + 7)

struct P{
	ll a[N][N];
	P(){std::memset(a,0,sizeof(a));}
}ans,A;

ll n,m;

P operator * (P x,P y){
	P ret;
	for(int i = 1;i <= m;++i)
	for(int j = 1;j <= m;++j)
	for(int k = 1;k <= m;++k)
	ret.a[i][j] = (ret.a[i][j] + x.a[i][k] * y.a[k][j]) % mod;
	return ret;
}

inline void fpow(ll rest){
	while(rest){
		if(rest & 1)ans = ans * A;
		rest >>= 1;
		A = A * A;
	}
}

int main(){
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i < m;++i)ans.a[1][i] = 1;
	ans.a[1][m] = 2;
	for(int i = 1;i < m;++i)A.a[i + 1][i] = 1;
	A.a[1][m] = A.a[m][m] = 1;
	fpow(n - m);
	std::cout<<ans.a[1][m] % mod<<std::endl;
}


原文地址:https://www.cnblogs.com/dixiao/p/15407390.html