Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩阵快速幂)
题意:
一个魔法水晶可以分裂成m个水晶,求放满n个水晶的方案数(mol1e9+7)
思路:
线性dp,dp[i]=dp[i]+dp[i-m];
由于n到1e18,所以要用到矩阵快速幂优化
注意初始化
代码:
#include<bits/stdc++.h> using namespace std; #define mod 1000000007 typedef long long ll; #define MAX 105 const int N=105;//矩阵的大小 int T; ll n,m; ll add(ll a,ll b) { a%=mod; b%=mod; return (a+b)%mod; } struct hh { ll ma[N][N]; }a,res; hh multi(hh a,hh b) { hh tmp; memset(tmp.ma,0,sizeof(tmp.ma)); for(int i=0;i<N;i++) for(int j=0;j<N;j++) for(int k=0;k<N;k++) { tmp.ma[i][j]=add(tmp.ma[i][j],a.ma[i][k]*b.ma[k][j]); } return tmp; } void fast_pow(hh a,long long k) { memset(res.ma,0,sizeof(res.ma)); for(int i=0;i<N;i++)res.ma[i][i]=1; while(k>0) { if(k&1) res=multi(res,a); a=multi(a,a); k>>=1; } } int main() { while(~scanf("%lld%d",&n,&m)) { for(int i=1;i<=m;i++) a.ma[i][i-1]=1; a.ma[1][1]=a.ma[1][m]=1; fast_pow(a,n); printf("%lld\n",res.ma[1][1]); } return 0; }