当前位置: 首页 > 工具软件 > Magic Copy > 使用案例 >

D. Magic Gems(矩阵快速幂)

潘慈
2023-12-01

http://codeforces.com/problemset/problem/1117/D

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Reziba has many magic gems. Each magic gem can be split into MM normal gems. The amount of space each magic (and normal) gem takes is 11 unit. A normal gem cannot be split.

Reziba wants to choose a set of magic gems and split some of them, so the total space occupied by the resulting set of gems is NN units. If a magic gem is chosen and split, it takes MM units of space (since it is split into MM gems); if a magic gem is not split, it takes 11 unit.

How many different configurations of the resulting set of gems can Reziba have, such that the total amount of space taken is NN units? Print the answer modulo 10000000071000000007 (109+7109+7). Two configurations are considered different if the number of magic gems Reziba takes to form them differs, or the indices of gems Reziba has to split differ.

Input

The input contains a single line consisting of 22 integers NN and MM (1≤N≤10181≤N≤1018, 2≤M≤1002≤M≤100).

Output

Print one integer, the total number of configurations of the resulting set of gems, given that the total amount of space taken is NN units. Print the answer modulo 10000000071000000007 (109+7109+7).

Examples

input

Copy

4 2

output

Copy

5

input

Copy

3 2

output

Copy

3

Note

In the first example each magic gem can split into 22 normal gems, and we know that the total amount of gems are 44.

Let 11 denote a magic gem, and 00 denote a normal gem.

The total configurations you can have is:

  • 11111111 (None of the gems split);
  • 00110011 (First magic gem splits into 22 normal gems);
  • 10011001 (Second magic gem splits into 22 normal gems);
  • 11001100 (Third magic gem splits into 22 normal gems);
  • 00000000 (First and second magic gems split into total 44 normal gems).

Hence, answer is 55.

题意:给出n和m代表着n的空间,每个魔法石只占一个空间,可以选择分解一个魔法石生成m个普通石,一个普通石头占一个空间,最初有n个魔法师,问如何分解占满n空间的方案数,不同的魔法石分解的普通石的也算不同的方案。

通过简单观察可以知道是一个递推式  

f[i]表示用 i 个单位空间的方案数,答案即为 f[n]

递推式为f[n]=f[n-1]+f[n-m]

以m=4为例

左矩阵为:1 0 0 1

                  1 0 0 0

                  0 1 0 0

                  0 0 1 0

右矩阵为1

              1

              1

              1

有个例外的是当n<m时答案就是1

                  

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007 ;
int MAXN;
ll n;
struct Matrix
{
	ll mat[110][110];
	Matrix() {}
	Matrix operator*(Matrix const &b)const
	{
		Matrix res;
		memset(res.mat, 0, sizeof(res.mat));
		for (int i = 0 ;i < MAXN; i++)
		for (int j = 0; j < MAXN; j++)
		for (int k = 0; k < MAXN; k++)
			res.mat[i][j] = (res.mat[i][j]+this->mat[i][k] * b.mat[k][j])%mod;
		return res;
	}
};
Matrix pow_mod(Matrix base, ll n)
{
	Matrix res;
	memset(res.mat, 0, sizeof(res.mat));
	for (int i = 0; i < MAXN; i++)
		res.mat[i][i] = 1;
	while (n > 0)
	{
		if (n & 1) res = res*base;
		base = base*base;
		n >>= 1;
	}
	return res;
}
Matrix base,fi;
int main()
{
	cin>>n>>MAXN;
	if(n<MAXN)
	{
		printf("1\n");
		return 0;
	}
	int m=MAXN;
	Matrix fi,base;
	fi.mat[0][0]=1;
	fi.mat[0][m-1]=1;
	for(int i=1;i<m;i++) fi.mat[i][i-1]=1;
	for(int i=0;i<m;++i) base.mat[i][0]=1;
	Matrix ans=pow_mod(fi,n-m+1);
	ans=ans*base;
	printf("%lld\n",ans.mat[0][0]);
}

 

 类似资料: