HDU2604 Queuing
http://acm.hdu.edu.cn/showproblem.php?pid=2604
矩阵快速幂优化DP
\[dp[i][0]表示以00结尾\\
dp[i][1]表示以01结尾\\
dp[i][2]表示以10结尾\\
dp[i][3]表示以11结尾\\
dp[i][0]=dp[i-1][0]+dp[i-1][2]\\
dp[i][1]=dp[i-1][0]\\
dp[i][2]=dp[i-1][1]+dp[i-1][3]\\
dp[i][3]=dp[i-1][1]\\
初始矩阵:
\begin{equation}
\left[
\begin{array}{c}
dp_{i-1,0}\\
dp_{i-1,1}\\
dp_{i-1,2}\\
dp_{i-1,3}\\
\end{array}
\right]
\end{equation} \\
\]
\[转移矩阵:
\begin{equation}
\left[
\begin{array}{c}
1 & 0 & 1 & 0\\
1 & 0 & 0 & 0\\
0 & 1 & 0 & 1\\
0 & 1 & 0 & 0\\
\end{array}
\right]
\end{equation}
\]
\(C++ Code:\)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#define N 1000005
#define n 4
using namespace std;
int l,m;
struct mat
{
int a[5][5];
mat operator * (mat b)
{
mat c;
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
c.a[i][j]=0;
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%m;
return c;
}
}zero,zy,cs;
mat ksm(mat x,int y)
{
mat ans=zero;
while (y)
{
if (y&1)
ans=ans*x;
x=x*x;
y >>=1;
}
return ans;
}
int main()
{
zy.a[1][1]=1,zy.a[1][3]=1,zy.a[2][1]=1;
zy.a[3][2]=1,zy.a[3][4]=1,zy.a[4][2]=1;
for (int i=1;i<=n;i++)
zero.a[i][i]=1;
cs.a[1][1]=2,cs.a[2][1]=1,cs.a[3][1]=2,cs.a[4][1]=1;
while (scanf("%d%d",&l,&m)!=EOF)
{
if (l<=2)
{
switch (l)
{
case 0:
cout << 0 << endl;
break;
case 1:
cout << 2 << endl;
break;
case 2:
cout << 4 << endl;
break;
}
continue;
}
mat ans=ksm(zy,l-3)*cs;
int g=(ans.a[1][1]+ans.a[2][1]+ans.a[3][1]+ans.a[4][1])%m;
cout << g << endl;
}
}