D. Magic Gems

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
  1. 4 2
output

Copy
  1. 5
input

Copy
  1. 3 2
output

Copy
  1. 3

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.

题解:

  • 考虑 dpdp , f[i]f[i] 表示用 ii 个单位空间的方案数,答案即为 f[n]f[n].
  • 对于一个位置,我们可以放 MagicMagic 的,占 mm 空间,也可以放 NormalNormal 的,占 11 空间.
  • 转移方程即为 f[i]=f[i−1]+f[i−m]f[i]=f[i−1]+f[i−m] ,边界条件为 f[0]=f[1]=f[2]=…f[m−1]=1f[0]=f[1]=f[2]=…f[m−1]=1.
  • 直接转移是 O(n)O(n) 的,无法通过,需要矩阵优化.

也可以用杜教BM,求线性递推式;

参考代码:(矩阵快速幂)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define Mod 1000000007
  5. const double PI = acos(-1.0);
  6. const double eps = 1e-;
  7. const int INF = 0x3f3f3f3f;
  8. const int N = + ;
  9. struct Matrix {
  10. ll n , m;
  11. ll grid[N][N];
  12. Matrix () { n = m = ; memset(grid , , sizeof(grid)); }
  13. };
  14.  
  15. Matrix mul(Matrix a,Matrix b)
  16. {
  17. Matrix c;
  18. c.n = a.n;c.m = b.m;
  19. for(ll i=;i<=c.n;++i)
  20. for(ll j=;j<=c.m;++j)
  21. {
  22. ll cnt = ;
  23. for(ll k=;k<=a.m;++k)
  24. {
  25. c.grid[i][j] = (c.grid[i][j] + a.grid[i][k] * b.grid[k][j]);
  26. cnt++;
  27. if(cnt % == ) c.grid[i][j] %= Mod;
  28. }
  29. c.grid[i][j] %= Mod;
  30. }
  31. return c;
  32. }
  33. Matrix QuickMul(Matrix a ,ll k)
  34. {
  35. if(k == ) return a;
  36. Matrix mid = QuickMul(a ,(k >> ));
  37. if(k & ) return mul(mul(mid , mid),a);
  38. else return mul(mid , mid);
  39. }
  40. ll n , m;
  41. int main()
  42. {
  43. cin >> n >> m;
  44. if(n < m) {return puts("") , ;}
  45. if(n == m) return puts("") , ;
  46. Matrix basic; basic.n = m; basic.m = ;
  47. for(ll i=;i<=m;++i) basic.grid[i][] = (i == m) ? : ;//{1,1,1...1,m}T
  48. Matrix base; base.n = base.m = m;
  49.  
  50. for(ll i = ; i <= m - ; i++) base.grid[i][i + ] = ;
  51. base.grid[m][] = base.grid[m][m] = ;
  52.  
  53. Matrix ans = mul(QuickMul(base , n - m) , basic);
  54. cout << ans.grid[m][] << endl;
  55. return ;
  56. }

杜教BM

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define rep(i,a,n) for (int i=a;i<n;i++)
  4. #define per(i,a,n) for (int i=n-1;i>=a;i--)
  5. #define pb push_back
  6. #define mp make_pair
  7. #define all(x) (x).begin(),(x).end()
  8. #define fi first
  9. #define se second
  10. #define SZ(x) ((int)(x).size())
  11. typedef vector<int> VI;
  12. typedef long long ll;
  13. typedef pair<int,int> PII;
  14. const ll mod=;
  15. ll powmod(ll a,ll b) {ll res=;a%=mod; assert(b>=); for(;b;b>>=) { if(b&)res=res*a%mod; a=a*a%mod; } return res; }
  16. ll _,n,m,dp[];
  17. namespace linear_seq {
  18. const int N=;
  19. ll res[N],base[N],_c[N],_md[N];
  20. vector<ll> Md;
  21. void mul(ll *a,ll *b,int k)
  22. {
  23. rep(i,,k+k) _c[i]=;
  24. rep(i,,k) if (a[i]) rep(j,,k) _c[i+j]= (_c[i+j]+a[i]*b[j])%mod;
  25. for (int i=k+k-;i>=k;i--) if (_c[i])
  26. rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
  27. rep(i,,k) a[i]=_c[i];
  28. }
  29. int solve(ll n,VI a,VI b)
  30. {
  31. ll ans=,pnt=;
  32. int k=SZ(a);
  33. assert(SZ(a)==SZ(b));
  34. rep(i,,k) _md[k--i]=-a[i];_md[k]=;
  35. Md.clear();
  36. rep(i,,k) if (_md[i]!=) Md.push_back(i);
  37. rep(i,,k) res[i]=base[i]=;
  38. res[]=;
  39. while ((1ll<<pnt)<=n) pnt++;
  40. for (int p=pnt;p>=;p--)
  41. {
  42. mul(res,res,k);
  43. if ((n>>p)&)
  44. {
  45. for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
  46. rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
  47. }
  48. }
  49. rep(i,,k) ans=(ans+res[i]*b[i])%mod;
  50. if (ans<) ans+=mod;
  51. return ans;
  52. }
  53. VI BM(VI s) {
  54. VI C(,),B(,);
  55. int L=,m=,b=;
  56. rep(n,,SZ(s)) {
  57. ll d=;
  58. rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
  59. if (d==) ++m;
  60. else if (*L<=n) {
  61. VI T=C;
  62. ll c=mod-d*powmod(b,mod-)%mod;
  63. while (SZ(C)<SZ(B)+m) C.pb();
  64. rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
  65. L=n+-L; B=T; b=d; m=;
  66. } else {
  67. ll c=mod-d*powmod(b,mod-)%mod;
  68. while (SZ(C)<SZ(B)+m) C.pb();
  69. rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
  70. ++m;
  71. }
  72. }
  73. return C;
  74. }
  75. int gao(VI a,ll n) {
  76. VI c=BM(a);
  77. c.erase(c.begin());
  78. rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
  79. return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
  80. }
  81. };
  82. int main()
  83. {
  84. scanf("%lld%lld",&n,&m);
  85. vector<int> v;
  86. for(int i=;i<m;++i) v.push_back();
  87. for(ll i=;i<=m;++i) dp[i]=i+,v.push_back(dp[i]);
  88. for(int i=m+;i<=;++i) dp[i]=dp[i-]+dp[i-m],v.push_back(dp[i]);
  89.  
  90. printf("%lld\n",linear_seq::gao(v,n-)%mod);
  91. return ;
  92. }

CoderForces-Round60D(1117) Magic Gems的更多相关文章

  1. 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 P ...

  2. CF1117D Magic Gems

    CF1117D Magic Gems 考虑 \(dp\) , \(f[i]\) 表示用 \(i\) 个单位空间的方案数,答案即为 \(f[n]\). 对于一个位置,我们可以放 \(Magic\) 的, ...

  3. [递推+矩阵快速幂]Codeforces 1117D - Magic Gems

    传送门:Educational Codeforces Round 60 – D   题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem ...

  4. D. Magic Gems(矩阵快速幂 || 无敌杜教)

    https://codeforces.com/contest/1117/problem/D 题解:有一些魔法宝石,魔法宝石可以分成m个普通宝石,每个宝石(包括魔法宝石)占用1个空间,让你求占用n个空间 ...

  5. Educational Codeforces Round 60 D. Magic Gems

    易得递推式为f[i]=f[i-1]+f[i-M] 最终答案即为f[N]. 由于N很大,用矩阵快速幂求解. code: #include<bits/stdc++.h> using names ...

  6. 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,所以要用到矩阵快速幂优化 ...

  7. eduCF#60 D. Magic Gems /// 矩阵快速幂

    题目大意: 给定n m (1≤N≤1e18, 2≤M≤100) 一个魔法水晶可以分裂成连续的m个普通水晶 求用水晶放慢n个位置的方案modulo 1000000007 (1e9+7) input 4 ...

  8. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

  9. hdu 5727 Necklace dfs+二分图匹配

    Necklace/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5727 Description SJX has 2*N mag ...

随机推荐

  1. 本地通知-UILocalNotification

    第一步:创建本地推送 本地通知 UILocalNotification // 创建⼀一个本地推送 UILocalNotification * notification = [[UILocalNotif ...

  2. java编程思想第四版第六章总结

    1. 代码重构 为什么f要代码重构 第一次代码不一定是完美的, 总会发现更优雅的写法. 代码重构需要考虑的问题 类库的修改不会破坏客户端程序员的代码. 源程序方便扩展和优化 2. 包 创建一个独一无二 ...

  3. ZeroC ICE的远程调用框架 ThreadPool

    ThreadPool提供Reactor/Proactor服务,并且强偶合了Reactor(反应器)/Proactor(前摄器).不同于Reactor/Proactor使用线程池 进行事件处理的设计.如 ...

  4. usaco training <1.2 Your Ride Is Here>

    题面 Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often ...

  5. 024.掌握Pod-部署MongoDB

    一 前期准备 1.1 前置条件 集群部署:Kubernetes集群部署参考003--019. glusterfs-Kubernetes部署:参考<附010.Kubernetes永久存储之Glus ...

  6. vim的查找功能

    vim是一款强大的编辑器. 在vim下要查找字符串: 一,全匹配: 1,从上往下查找,比如“string” :   /string 2,从下往上查找,比如“string” : ?string 二,模糊 ...

  7. Missing radix parameter 错误的解决办法

    下载了Mint-Ui的example,使用npm run dev时发现如下报错: ERROR in ./packages/loadmore/src/loadmore.vue ✘ http://esli ...

  8. 【集训Day2 哈希表】【NHOI2015】【Luogu P2421】差

    LuoguP2421 原题来自NHOI2015 [解题思路] 本题的解题方法有三种,一种为枚举减数,二分查找被减数.第二种为利用数据单调性用尺取法进行查找,第三种为运用哈希表以快速查找数据. [解题反 ...

  9. LeetCode 5276. 不浪费原料的汉堡制作方案 Number of Burgers with No Waste of Ingredients

    地址 https://leetcode-cn.com/problems/number-of-burgers-with-no-waste-of-ingredients/ 目描述圣诞活动预热开始啦,汉堡店 ...

  10. 2场 J -Subarray

    题意: 长度为1e91e9的(1,−1)(1,−1)序列,下标从00到1e9−11e9−1,已知有nn个区间为11,其他为−1−1, 问存在多少个区间的和>1>1(保证∑1≤i≤nr[i] ...