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[ egin{matrix} 2&0&2\ 0&2&2\ 1&1&2 end{matrix} ight] ]

接下来就是套模板了。

#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;
	}
}
原文地址:https://www.cnblogs.com/iss-ue/p/12612726.html