Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

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 (1N10^18, 2M100).

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 }

猜你喜欢

转载自www.cnblogs.com/npugen/p/10786334.html