CoderForces-Round60D(1117) Magic Gems
D. Magic Gems
3 seconds
256 megabytes
standard input
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.
The input contains a single line consisting of 22 integers NN and MM (1≤N≤10181≤N≤1018, 2≤M≤1002≤M≤100).
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).
4 2
5
3 2
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,求线性递推式;
参考代码:(矩阵快速幂)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Mod 1000000007
const double PI = acos(-1.0);
const double eps = 1e-;
const int INF = 0x3f3f3f3f;
const int N = + ;
struct Matrix {
ll n , m;
ll grid[N][N];
Matrix () { n = m = ; memset(grid , , sizeof(grid)); }
}; Matrix mul(Matrix a,Matrix b)
{
Matrix c;
c.n = a.n;c.m = b.m;
for(ll i=;i<=c.n;++i)
for(ll j=;j<=c.m;++j)
{
ll cnt = ;
for(ll k=;k<=a.m;++k)
{
c.grid[i][j] = (c.grid[i][j] + a.grid[i][k] * b.grid[k][j]);
cnt++;
if(cnt % == ) c.grid[i][j] %= Mod;
}
c.grid[i][j] %= Mod;
}
return c;
}
Matrix QuickMul(Matrix a ,ll k)
{
if(k == ) return a;
Matrix mid = QuickMul(a ,(k >> ));
if(k & ) return mul(mul(mid , mid),a);
else return mul(mid , mid);
}
ll n , m;
int main()
{
cin >> n >> m;
if(n < m) {return puts("") , ;}
if(n == m) return puts("") , ;
Matrix basic; basic.n = m; basic.m = ;
for(ll i=;i<=m;++i) basic.grid[i][] = (i == m) ? : ;//{1,1,1...1,m}T
Matrix base; base.n = base.m = m; for(ll i = ; i <= m - ; i++) base.grid[i][i + ] = ;
base.grid[m][] = base.grid[m][m] = ; Matrix ans = mul(QuickMul(base , n - m) , basic);
cout << ans.grid[m][] << endl;
return ;
}
杜教BM
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=;
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; }
ll _,n,m,dp[];
namespace linear_seq {
const int N=;
ll res[N],base[N],_c[N],_md[N];
vector<ll> Md;
void mul(ll *a,ll *b,int k)
{
rep(i,,k+k) _c[i]=;
rep(i,,k) if (a[i]) rep(j,,k) _c[i+j]= (_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-;i>=k;i--) if (_c[i])
rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b)
{
ll ans=,pnt=;
int k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,,k) _md[k--i]=-a[i];_md[k]=;
Md.clear();
rep(i,,k) if (_md[i]!=) Md.push_back(i);
rep(i,,k) res[i]=base[i]=;
res[]=;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=;p--)
{
mul(res,res,k);
if ((n>>p)&)
{
for (int i=k-;i>=;i--) res[i+]=res[i];res[]=;
rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,,k) ans=(ans+res[i]*b[i])%mod;
if (ans<) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(,),B(,);
int L=,m=,b=;
rep(n,,SZ(s)) {
ll d=;
rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==) ++m;
else if (*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+-L; B=T; b=d; m=;
} else {
ll c=mod-d*powmod(b,mod-)%mod;
while (SZ(C)<SZ(B)+m) C.pb();
rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
};
int main()
{
scanf("%lld%lld",&n,&m);
vector<int> v;
for(int i=;i<m;++i) v.push_back();
for(ll i=;i<=m;++i) dp[i]=i+,v.push_back(dp[i]);
for(int i=m+;i<=;++i) dp[i]=dp[i-]+dp[i-m],v.push_back(dp[i]); printf("%lld\n",linear_seq::gao(v,n-)%mod);
return ;
}
CoderForces-Round60D(1117) Magic Gems的更多相关文章
- 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 ...
- CF1117D Magic Gems
CF1117D Magic Gems 考虑 \(dp\) , \(f[i]\) 表示用 \(i\) 个单位空间的方案数,答案即为 \(f[n]\). 对于一个位置,我们可以放 \(Magic\) 的, ...
- [递推+矩阵快速幂]Codeforces 1117D - Magic Gems
传送门:Educational Codeforces Round 60 – D 题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem ...
- D. Magic Gems(矩阵快速幂 || 无敌杜教)
https://codeforces.com/contest/1117/problem/D 题解:有一些魔法宝石,魔法宝石可以分成m个普通宝石,每个宝石(包括魔法宝石)占用1个空间,让你求占用n个空间 ...
- 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 ...
- 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,所以要用到矩阵快速幂优化 ...
- eduCF#60 D. Magic Gems /// 矩阵快速幂
题目大意: 给定n m (1≤N≤1e18, 2≤M≤100) 一个魔法水晶可以分裂成连续的m个普通水晶 求用水晶放慢n个位置的方案modulo 1000000007 (1e9+7) input 4 ...
- Educational Codeforces Round 60 (Rated for Div. 2) 题解
Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...
- hdu 5727 Necklace dfs+二分图匹配
Necklace/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5727 Description SJX has 2*N mag ...
随机推荐
- 深入理解计算机系统 第八章 异常控制流 part1
本章主旨 第八章的目的是阐述清楚应用程序是如何与操作系统交互的(之前章节的学习是阐述应用程序是如何与硬件交互的) 异常控制流 异常控制流,即 ECF(exceptional contril flow) ...
- C#语音特性 很实用
1.隐式类型 Var 2.匿名类型 new{} 3.自动属性 [prop TAB] public string Title { get; set; } 4.初始化器 var myObj1 = ne ...
- PHP7中的异常与错误处理
PHP 中的 Exception, Error, Throwable PHP 中将代码自身异常(一般是环境或者语法非法所致)称作错误 Error,将运行中出现的逻辑错误称为异常 Exception 错 ...
- [spark程序]统计人口平均年龄(本地文件)(详细过程)
一.题目描述 (1)编写Spark应用程序,该程序可以在本地文件系统中生成一个数据文件peopleage.txt,数据文件包含若干行(比如1000行,或者100万行等等)记录,每行记录只包含两列数据, ...
- nyoj 68-三点顺序(叉积)
68-三点顺序 内存限制:64MB 时间限制:1000ms 特判: No 通过数:3 提交数:5 难度:3 题目描述: 现在给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,现在让你判断A ...
- 深度剖析Javascript执行环境、作用域链
一.执行环境 执行环境(也叫做执行上下文,Execution Context)是Javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问其他数据,决定了它们各自的行为.每个执行环境都 ...
- SpringBoot系列之切换log4j日志框架
SpringBoot系列之使用切换log4j日志框架 ok,在pom文件右键->Diagrams->show Dependencies....,如图,找到spring-boot-start ...
- [Windows篇] 在windows 10上源码编译gtest 并编写CMakeLists.txt
本文首发于个人博客https://kezunlin.me/post/aca50ff8/,欢迎阅读! compile gtest on windows 10 Guide compile gtest on ...
- 2019-9-24:渗透测试,css样式,js基础学习笔记
css分组和嵌套:分组:比如有<h1><h4><p>,3个标签,设置css时候可以 h1,h4,p{样式:属性} 这样的语法嵌套:比如.lei{样式:属性},.le ...
- DBEntry.Net 简介
[尊重作者:本文转自:http://www.cnblogs.com/lephone/] 这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问 ...