Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems
Time Limit: 3000 mSec
Problem Description
Input
The input contains a single line consisting of 2 integers N and M (1≤N≤10^18, 2≤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 N units. Print the answer modulo 1000000007.
Sample Input
4 2
Sample Output
5
题解:很简单的dp,考虑第一个数分裂不分裂,dp[n] = dp[n - m] + dp[n - 1],其中dp[n]就是站n个单位空间的方法数,由于N比较大,所以很明显要用矩阵快速幂,写这篇题解同时提醒自己快速幂之前一定要判断指数是否非负。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 100 + 5; 9 const int maxm = 200000 + 100; 10 const int maxs = 10000 + 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const double eps = 1e-14; 19 const double inf = 1e15; 20 const double pi = acos(-1.0); 21 const int SIZE = 100 + 5; 22 const LL MOD = 1000000007; 23 24 struct Matrix 25 { 26 int r, c; 27 LL mat[SIZE][SIZE]; 28 Matrix() {} 29 Matrix(int _r, int _c) 30 { 31 r = _r; 32 c = _c; 33 memset(mat, 0, sizeof(mat)); 34 } 35 }; 36 37 Matrix operator*(Matrix a, Matrix b) 38 { 39 Matrix s(a.r, b.c); 40 for (int i = 0; i < a.r; i++) 41 { 42 for (int k = 0; k < a.c; k++) 43 { //j, k交换顺序运行更快 44 for (int j = 0; j < b.c; j++) 45 { 46 s.mat[i][j] = (s.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD; 47 } 48 } 49 } 50 return s; 51 } 52 53 Matrix pow_mod(Matrix a, LL n) 54 { 55 Matrix ret(a.r, a.c); 56 for (int i = 0; i < a.r; i++) 57 { 58 ret.mat[i][i] = 1; //单位矩阵 59 } 60 Matrix tmp(a); 61 while (n) 62 { 63 if (n & 1) 64 ret = ret * tmp; 65 tmp = tmp * tmp; 66 n >>= 1; 67 } 68 return ret; 69 } 70 71 LL n, m; 72 73 int main() 74 { 75 ios::sync_with_stdio(false); 76 cin.tie(0); 77 //freopen("input.txt", "r", stdin); 78 //freopen("output.txt", "w", stdout); 79 cin >> n >> m; 80 if (n < m) 81 { 82 cout << 1 << endl; 83 return 0; 84 } 85 Matrix ori = Matrix(m, 1); 86 for (int i = 0; i < m; i++) 87 { 88 ori.mat[i][0] = unit; 89 } 90 Matrix A = Matrix(m, m); 91 A.mat[0][0] = unit; 92 A.mat[0][m - 1] = unit; 93 for (int i = 1; i < m; i++) 94 { 95 A.mat[i][i - 1] = unit; 96 } 97 Matrix ans = pow_mod(A, n - m + 1); 98 ori = ans * ori; 99 cout << ori.mat[0][0] << endl; 100 return 0; 101 }