1. 程式人生 > >Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩陣快速冪)

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

tmp hid 由於 isp targe tar pre 魔法 lld

題目傳送門

題意:

一個魔法水晶可以分裂成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; }
View Code

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