矩阵快速幂优化dp
寻址连续优化
for(int i = 1; i <= n; i++)
for(int k = 1; k <= n; k++)
if(a.a[i][k])
for(int j = 1; j <= n; j++)
c.a[i][j] = (c.a[i][j] + 1ll * a.a[i][k] * b.a[k][j]) % mod;
P3216 [HNOI2011]数学作业 (普通套路)
题目
题解
设
然后有
CF514E Darth Vader and Tree (较大矩阵的矩阵快速幂)
题面
有一个无限大的有根树,树上的每一个节点都有
给出一个数
题解
设
显然有
实际上,我们只关心每种
设
P2579 [ZJOI2005]沼泽鳄鱼 (邻接矩阵与矩阵快速幂)
题目
给定
给定起点终点,求经过
题解
所以开十二个邻接矩阵即可, 每个矩阵表示当前走一步的合法情况
答案为
P3176 [HAOI2015]数字串拆分(对拆分函数的处理)
题解
首先,显然有
注意到
令
举个例子
时间复杂度
CF576D Flights for Regular Customers (动态变化的图)
题目
- 给定一张
个点 条边的有向图。 - 一开始你在
号节点,你要走到 号节点去。 - 只有当你已经走过了至少
条边时,你才能走第 条边。 - 问最少要走多少条边,或判断无法到达。
, 。
题解
首先对边按照
每个点的状态只有 0/1 两种,分别对应着无法到达和可以到达,因此可以 bitset 优化,时间复杂度
P6772 [NOI2020] 美食家 (拆点和预处理倍增矩阵)
题解
首先,边长
具体来说,就是将点
边权为
至于美食节的条件,我们参考 CF576D 的做法,将
考虑优化,我们发现这一次次的矩阵快速幂中,每次都倍增着去做显然是有重复计算的,因此我们可以用
ZR2023 CSP7连测 Day1 T3 (小模数循环节的利用)
题意
小X设想的
每一个时刻,土拨鼠会离开当前所在的土豆田去往下一块土豆田。若土拨鼠当前所在的土豆田编号为
小X想知道,对于给定的正整数
由于答案可能很大,小X只要知道这个方案数对
题解
线性dp是容易的
即考虑从
由于
但是这并没有什么作用,因为我们乘的矩阵每一次都不一样
注意到模数很小,而众所周知模数是可以直接模到矩阵内每一项的,因此矩阵有一个长度为
时间复杂度
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read()
{
ll x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
return x*f;
}
const int mod=2027;
ll n;
int m;
bool S[16];
struct matrix{
int z[16][16];
inline void reset(){
memset(z,0,sizeof(z));
}
matrix(){
reset();
}
void init()
{
for(int i=1;i<=15;++i) z[i][i]=1;
}
void getmtx(int x)
{
for(int i=1;i<=15;++i)
if(S[i]) z[1][i]=(x-i+1+mod)%mod;
for(int i=2;i<=15;++i) z[i][i-1]=1;
}
matrix operator *(const matrix &w)const{
matrix ans;
for(int i=1;i<=15;++i)
for(int j=1;j<=15;++j)
for(int k=1;k<=15;++k)
ans.z[i][j]=(ans.z[i][j]+z[i][k]*w.z[k][j]%mod)%mod;
return ans;
}
};
matrix ksm(matrix a,ll b)
{
matrix res;res.init();
while(b)
{
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++) S[read()]=1;
matrix trans,ans;
trans.init();
ans.init();
for(int i=1;i<=mod;i++)
{
matrix w;
w.getmtx(i);
trans=w*trans;
if(n%mod==i)ans=trans;
}
ans=ans*ksm(trans,n/mod);
cout<<ans.z[1][1]<<'\n';
return 0;
}
posted on 2023-10-27 18:06 star_road_xyz 阅读(87) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】