P4159 迷路题解

P4159 迷路#

A small trick about Matrix#

首先介绍一个有关邻接矩阵非常神奇的性质

假如我们现在有一个邻接矩阵 A ,并且边是没有边权的 (即只有 0/1)

我们用 Ax 表示矩阵 Ax 次方

那么我们有:Ai,jx 表示 i 经过 x 条边抵达 j 的方案数

至于为什么可以感性理解一下:

根据矩阵乘法的定义,我们显然有:

Ai,jx=Ai,kx1×Aj,k

也就可以理解成:从 ix 条边到 j 相当于先走 x1 条边到 k 再从 k 走一条边到 j

思路

回到这道题

由于此题每条边边权 w 满足 1w9,显然我们不能直接利用上面的 trick

但是由于 w 很小,我们可以考虑把每 1 个点都拆成 9 个点来考虑

然后用矩阵快速幂搞就可以了

注:交的时候卡了下常,放的代码把 IO 去了

code

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define re register

const int mod=2009;

struct matrix{
	int n,A[181][181];
	inline matrix(re int x){n=x,memset(A,0,sizeof(A));}
	inline matrix operator *(const matrix B) const{
		matrix C(n);
		for(re int i=1;i<=n;++i)
			for(re int j=1;j<=n;++j)
				for(re int k=1;k<=n;++k)
					C.A[i][j]=(C.A[i][j]+A[i][k]*B.A[k][j])%mod;
		return C;
	}
	inline matrix operator ^(const int idx) const{
		matrix res(n),B=*this;
        for(re int i=1;i<=n;++i)
			res.A[i][i]=1;
		for(re int qwq=idx;qwq;qwq>>=1,B=B*B)
			if(qwq&1) res=res*B;
		return res;
	}
};

int n,m;

inline int get_num(re int x,re int y){
	return (x-1)*10+y;
}

signed main(){
	read(n),read(m);
	matrix f(180);
	for(re int i=1;i<=n;++i){
		for(re int j=1;j<10;++j)
			f.A[get_num(i,j)][get_num(i,j+1)]=1;
		for(re int j=1;j<=n;++j){
			re int x;
			scanf("%1d",&x);
			if(x) f.A[get_num(i,x)][get_num(j,1)]=1;
		}
	}
	f=f^m;
	write(f.A[1][10*n-9]);
}

作者:Into_qwq

出处:https://www.cnblogs.com/into-qwq/p/16532420.html

版权:本作品采用「qwq」许可协议进行许可。

posted @   Into_qwq  阅读(31)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示