Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩阵快速幂)

时间:2023-03-09 19:38:31
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,所以要用到矩阵快速幂优化

Educational Codeforces Round 60 (Rated for Div. 2)  D. Magic Gems(矩阵快速幂)

注意初始化

代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long ll;
#define MAX 105
const int N=;//矩阵的大小
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,,sizeof(tmp.ma));
for(int i=;i<N;i++)
for(int j=;j<N;j++)
for(int k=;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,,sizeof(res.ma));
for(int i=;i<N;i++)res.ma[i][i]=;
while(k>)
{
if(k&) res=multi(res,a);
a=multi(a,a);
k>>=;
}
}
int main()
{
while(~scanf("%lld%d",&n,&m))
{
for(int i=;i<=m;i++) a.ma[i][i-]=;
a.ma[][]=a.ma[][m]=;
fast_pow(a,n);
printf("%lld\n",res.ma[][]);
}
return ;
}