https://codeforces.com/contest/1117/problem/D

题解:有一些魔法宝石,魔法宝石可以分成m个普通宝石,每个宝石(包括魔法宝石)占用1个空间,让你求占用n个空间的方法有几种,有不同数量的魔法宝石和不同分法的方法算不同的方法,

分析:根据一些猜想可以推出递推式f[n]=f[n-1]+f[n-m]  ; 答案也比较好猜想,牺牲一个然后分解 m 个

然后就是简单的构造矩阵快速幂

或者使用无敌杜教

这里给出点杜教心得 , 有时候并不是只用给出8项 , 而是给的数据越多 , 答案越正确 , 所以有时候用杜教不过就考虑给许多许多项杜教 , 可以在时间运行下的极限

矩阵快速幂

#include<stdio.h>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
typedef vector<ll>vec;
typedef vector<vec>mat; const int M = ;
ll n;int m;
int V;
mat mul(mat &A , mat &B)
{
mat C(A.size() , vec(B.size()));
for(int i= ; i<A.size() ; i++)
{
for(int k= ; k<B.size() ; k++)
{
if(A[i][k]==)
continue;
for(int j= ; j<B[].size() ; j++)
{
if(B[k][j]==)
continue;
C[i][j] = (C[i][j]%M+A[i][k]*B[k][j]%M)%M;
}
}
}
return C;
}
mat pow(mat A,ll n)
{
mat B(A.size(),vec(A.size()));
for(int i= ; i<A.size() ; i++)
B[i][i]=; while(n>)
{
if(n&)
B = mul(B,A);
A = mul(A,A);
n >>= ;
}
return B;
}
void so( )
{
mat A(m,vec(m));///构造矩阵
// A[0][0]=1;A[0][1]=2;A[0][2]=1;A[0][3]=0;A[0][4]=0;A[0][5]=0;
// A[1][0]=1;A[1][1]=0;A[1][2]=0;A[1][3]=0;A[1][4]=0;A[1][5]=0;
// A[2][0]=0;A[2][1]=0;A[2][2]=1;A[2][3]=3;A[2][4]=3;A[2][5]=1;
// A[3][0]=0;A[3][1]=0;A[3][2]=0;A[3][3]=1;A[3][4]=2;A[3][5]=1;
// A[4][0]=0;A[4][1]=0;A[4][2]=0;A[4][3]=0;A[4][4]=1;A[4][5]=1;
// A[5][0]=0;A[5][1]=0;A[5][2]=0;A[5][3]=0;A[5][4]=0;A[5][5]=1;
//printf("520");
for(int i= ; i<m ; i++)
for(int j= ; j<m ; j++)
A[i][j]=;
A[][]=;A[][m-]=;
for(int i= ; i<m ; i++)
A[i][i-]=; A = pow(A,n-m+);///第m项没有算哦
ll ans=;
for(int i= ; i<m ; i++)
{ ans=(ans+A[][i]+M)%M; } printf("%lld\n",(ans+M)%M); } int main()
{ scanf("%lld%d",&n,&m); so(); return ;
}

牛逼杜教

#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;
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)));
}
};
ll f[];
int main()
{
ll n,m;
scanf("%lld%lld",&n,&m);
for(int i=;i<=m;i++) f[i]=;
for(int i=m;i<=;i++)
f[i]=(f[i-]+f[i-m])%mod;
vector<int>v;
n++;
for(int i=;i<=;i++)
v.push_back(f[i]); //至少8项,越多越好。
printf("%lld\n",linear_seq::gao(v,n-)%mod);
}

D. Magic Gems(矩阵快速幂 || 无敌杜教)的更多相关文章

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

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

  2. 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 ...

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

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

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

  5. poj 2888 Magic Bracelet(Polya+矩阵快速幂)

    Magic Bracelet Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 4990   Accepted: 1610 D ...

  6. ZZNU 2182 矩阵dp (矩阵快速幂+递推式 || 杜教BM)

    题目链接:http://47.93.249.116/problem.php?id=2182 题目描述 河神喜欢吃零食,有三种最喜欢的零食,鱼干,猪肉脯,巧克力.他每小时会选择一种吃一包. 不幸的是,医 ...

  7. HDU4887_Endless Punishment_BSGS+矩阵快速幂+哈希表

    2014多校第一题,当时几百个人交没人过,我也暴力交了几发,果然不行. 比完了去学习了BSGS才懂! 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4887 ...

  8. HDU 5171 GTY's birthday gift 矩阵快速幂

    GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  9. ACM-ICPC 2018 焦作赛区网络预赛 L Poor God Water(矩阵快速幂,BM)

    https://nanti.jisuanke.com/t/31721 题意 有肉,鱼,巧克力三种食物,有几种禁忌,对于连续的三个食物:1.这三个食物不能都相同:2.若三种食物都有的情况,巧克力不能在中 ...

随机推荐

  1. Docker01 centos系统安装、centos安装docker、docker安装mongoDB

    1 centos系统安装 本博文是基于 centos6.5 的,利用VMware 虚拟机搭建 centos6.5 系统 1.1 centos6.5资源获取 1.2 安装 1.2.1 新建虚拟机 1.2 ...

  2. commons-X系列

    1 commons-lang 1.1 ReflectionToStringBuilder 将对象进行字符串拼接 /* * Licensed to the Apache Software Foundat ...

  3. Hyperledger Fabric系统架构

  4. c语言实践 1/1-1/2+1/3-1/4+...

    其实这个题目和上面那个是一样的 /* 1/1-1/2+1/3-1/4+...1/n; */ int n = 1; double sum = 0; double frac = 0; int i = 1; ...

  5. jqgrid常用操作

    .jqgrid控件列在需要的地方加上edittable=true <asp:JQGrid runat=" DataUrl="/ccr/CcrCompanyPromoterMa ...

  6. 第二章启程前的认知准备,2.1Opencv官方例程引导与赏析

    1.在opencv安装目录下,可以找到opencv官方提供的示例代码,具体位于...\opencv\sources\samples目录下,如下所示 名为c的文件夹存放着opencv1.0等旧版本的示例 ...

  7. Nanami's Digital Board

    题意: 给出点(x1,y1),求以x=x1为上边界,或下边界:以y=y1为左边界,或右边界矩形的最大值(矩形内所有的点均为1) 定义四个数组lft[][],rht[][],up[][],down[][ ...

  8. Dapper多表查询

    1对1 //文章 public class Post { public int ID { get; set; } public string Title { get; set; } public st ...

  9. .NET和C#的版本历史

    维基百科页面:https://en.wikipedia.org/wiki/.NET_Framework_version_history Versionnumber CLRversion Release ...

  10. 初学python - 常见函数使用

    *** 读入两个整数 a,b=eval(input()) ***range()函数 创建列表 :range( 1, 11,2) - 产生 [1,11) 相差为2数,2为步长 ***print()函数 ...