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