Vijos P1603 迷宫
题目
背景
还是一道水题
描述
在某个神秘的星球上有一个游乐园
游乐园里有一个奇怪的迷宫,迷宫内有n个点,每个点之间都可能会有一条有向边(可能会有自环)
现在游乐园主有个问题想请你帮忙:
问:从s点走到f点,恰好走过m条边(边可以重复走),总共有多种不同的方案(两种方案只要有一条边不同,就是不同方案)
现在你只需要输出方案数对P取模的结果就可以了
格式
输入格式
一个整数n
下面跟着n行n列的邻接矩阵,两个数之间有一个空格
在下一行依次是整数m,s,f,p
1<=n,s,f<=50
1<=m<=10^6
1<=p<=10^5
输出格式
一个数即方案数对P取模的结果
样例1
样例输入1
5
0 1 1 1 1
0 0 0 0 0
1 1 0 1 1
0 0 0 0 1
0 0 0 0 1
3 1 5 1994
样例输出1
5
限制
各个测试点1s
题解
快速幂+矩阵乘法(第一次打矩阵乘法+重载运算符,打得乱七八糟的。。。)
代码
首先是矩阵乘法
矩阵乘法的运算方式就是把 (i,k) 和 (k,j) 的乘积转移到 (i,j) 上
在该题目中就表示从
i
到
然后是重载运算符,就是把某一种数据体的某种运算进行修改
比如,这里的代码就是重载矩阵的乘法运算
matrix operator *(matrix a,matrix b)
{
matrix c;
zero(c); //表示将矩阵c清零
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
c.s[i][j]=(c.s[i][j]+(a.s[i][k]*b.s[k][j])%p)%p;
return c;
}
然后就是快速幂
快速幂的原理就是把
xy
中的
y
转换成二进制得到一个数组
然后我们就可以用 log2(y) 的时间算出 xy
下面是矩阵的快速幂
matrix pow(matrix x,int y)
{
matrix s;
one(s);//初始化,将(i,i)的值记为1
while (y) {if (y&1) s=s*x;y>>=1;x=x*x;}
return s;
}