题目

传送门:QWQ

分析

因为m很小,考虑把所有状态压成m位二进制数。

那么总状态数小于$ 2^5 $。

如果状态$ i $能转移到$ j $,那么扔进一个矩阵,n次方快速幂一下。

答案是对角线之和,是转移n次后回来的方案数。

代码

 #include <bits/stdc++.h>
typedef long long ll;
const int maxn=;
const ll MOD=;
using namespace std;
ll tot; int sta[maxn];
struct Matrix{
ll m[maxn][maxn];
Matrix(){memset(m,,sizeof(m));}
};
Matrix operator * (const Matrix& a,const Matrix& b){
Matrix ans;
for(int i=;i<=tot;i++)
for(int j=;j<=tot;j++)
for(int k=;k<=tot;k++)
ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j])%MOD;
return ans;
}
Matrix a,ans,f,tmp;
int main(){
ll n,m;int k;
cin>>n>>m>>k;
tot=(<<m)-;
for(int i=;i<=tot;i++){
int num=,x=i;
while(x){ if(x&)num++; x>>=; }
if(num<=k){
sta[i]=true;
a.m[i>>][i]=;
a.m[(i>>)+(<<(m-))][i]=;
}
} for(int i=;i<maxn;i++) tmp.m[i][i]=;
while(n){
if(n&) tmp=tmp*a;
a=a*a;
n>>=;
} // for(int i=0;i<=tot;i++,puts(""))
// for(int j=0;j<=tot;j++)
// printf("%5d ",tmp.m[i][j]);
ll cnt=;
for(int i=;i<=tot;i++){
if(sta[i]){
cnt=(cnt+tmp.m[i][i])%MOD;
}
}
cout<<cnt<<endl;
return ;
}

最新文章

  1. 【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
  2. 《C++primer》v5 第4章 表达式 读书笔记 习题答案
  3. java之数组
  4. Linux Apache和Nginx的比较
  5. Win7+VMware Workstation环境下的CentOS-Linux网络连接设置
  6. Objective-C语法之代码块(block)的使用
  7. 【HDOJ】1648 Keywords
  8. 使用JDK自带jvisualvm监控tomcat
  9. PHP代码,拒绝频繁访问
  10. poj 1050 To the Max_dp求最大子矩阵和
  11. Magento布局layout.xml文件详解
  12. ASP.NET MVC C#知识点提要
  13. java数组去重
  14. 【20181031】arcgis10.6破解不成功的问题
  15. ubuntu下没有ping命令
  16. javascript 高级程序设计 一
  17. MFC模块状态(二)AFX_MANAGE_STATE(AfxGetStaticModuleState())
  18. PostgreSQL LIKE 查询效率提升实验&lt;转&gt;
  19. 一文学会最常见的10种NLP处理技术
  20. TScrollBox响应鼠标滚轮问题

热门文章

  1. 部署python3.6下的django
  2. HandBrake 开源视频转码器、编码转换器、格式转换器
  3. 简单shell实现局域网IP扫描
  4. HDU 4862
  5. matlab fgetl()
  6. django所遇到问题简单总结
  7. WPF优化体验&lt;一&gt;(转)
  8. java面试笔试题收集
  9. 【转】每天一个linux命令(53):route命令
  10. 管理node.js版本的模块:n