51nod_1122:机器人走方格 V4 (矩阵快速幂)

时间:2021-10-27 18:21:44

题目链接

昨天上随机信号分析讲马氏链的时候突然想到这题的解法,今天写一下

定义矩阵A,Ans=A^n,令A[i][j]表示,经过1次变换后,第i个位置上的机器人位于第j个位置的情况数,则Ans[i][j]表示最初在第i个位置上的机器人n次变换后位于第j个位置的情况数

最后求一下任意两个机器人不在相同位置的情况数之和(注意乘法原理和加法原理的应用)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int N=;
const LL mod=1e9+; LL hh[N][N]= {{,,,},
{,,,},
{,,,},
{,,,}
}; struct Mat
{
LL mat[N][N];
Mat()
{
memset(mat,,sizeof(mat));
}
LL* operator [](int x) //注意这种写法
{
return mat[x];
}
} A;
Mat Mut(Mat a,Mat b)
{
Mat c;
for(int k=; k<N; k++)
for(int i=; i<N; i++)
for(int j=; j<N; j++)
{
c[i][j]+=a[i][k]*b[k][j]%mod;
c[i][j]=c[i][j]%mod;
}
return c;
}
Mat Qpow(Mat a,LL n)
{
Mat c;
for(int i=; i<N; ++i)
c[i][i]=;
for(; n; n>>=)
{
if(n&) c=Mut(c,a);
a=Mut(a,a);
}
return c;
} void init_A()
{
for(int i=; i<N; i++)
for(int j=; j<N; j++)
A[i][j]=hh[i][j];
} int main()
{
LL n,Fn,Gn;
init_A();
while(cin>>n)
{
Mat Ans=Qpow(A,n);
LL sum=;
for(int i1=; i1<; i1++)
for(int i2=; i2<; i2++)
for(int i3=; i3<; i3++)
for(int i4=; i4<; i4++)
if(i1!=i2&&i1!=i3&&i1!=i4&&i2!=i3&&i2!=i4&&i3!=i4)
{
sum+=Ans[][i1]*Ans[][i2]%mod*Ans[][i3]%mod*Ans[][i4]%mod;
sum%=mod;
}
cout<<sum<<endl;
}
}