POJ3734(矩阵快速幂)

\(假设现在到第i个积木\)

\(红绿恰都是偶数a种方案,恰都是奇数为b种方案,一奇一偶为c种方案\)

\(由此考虑i+1个积木的情况\)

Ⅰ.一奇一偶的方案

\(如果第i层恰是奇数的情况,那么本次只要染色为红绿即可\)

\(如果第i层恰是偶数的情况,那么本次只要染色为红绿即可\)

\(如果第i层一奇一偶,那本次只要染色为蓝黄即可。\)

\(综上所诉,c1=a*2+b*2+c*2;\)

Ⅱ.恰为偶的方案

\(同理得,a1=a*2+c\)

Ⅲ.恰为奇的方案

\(同理得,b1=b*2+c\)

那么接下来就可以构造矩阵了。

\(对于|a,b,c|想得到|a*2+c,b*2+c,a*2+b*2+c*2|\)

在草稿纸上凑一凑就可以得到系数矩阵为

\[\left[
\begin{matrix}
2&0&2\\
0&2&2\\
1&1&2
\end{matrix}
\right]
\]

接下来就是套模板了。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int mod=10007;
struct rce{
int m[4][4];
rce(){memset(m,0,sizeof(m));}
};
rce operator * (rce a,rce b)
{
rce ans;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
ans.m[i][j]=0;
for(int k=1;k<=3;k++)
ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
}
return ans;
}
rce init()
{
rce temp;
for(int i=0;i<=3;i++) temp.m[i][i]=1;
return temp;
}
rce quickpow(rce a,int n)
{
rce ans=init();
while(n)
{
if(n&1) ans=ans*a;
a=a*a;
n>>=1;
}
return ans;
}
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
rce chu,xi;
chu.m[1][1]=2,chu.m[1][3]=2;
xi.m[1][1]=xi.m[1][3]=xi.m[2][2]=xi.m[2][3]=xi.m[3][3]=2;
xi.m[3][1]=xi.m[3][2]=1;//初始化系数矩阵
xi=quickpow(xi,n-1);
chu=chu*xi;
cout<<chu.m[1][1]%mod<<endl;
}
}
上一篇:【java】jstack


下一篇:POJ 3734 Blocks(矩阵快速幂+矩阵递推式)