您的位置:首页 > 其它

poj 3734 Blocks 递推+矩阵幂优化

2016-11-28 00:05 316 查看
点击打开链接

题意 n块block 可以涂上 R,B,G,Y 求n块涂色中 R,G颜色个数为偶数的方法数?

涂到第i块时:设ai RG都为偶数的方案数. bi RG恰好一个为偶数的方案数. ci:RG都为奇数的方案数

容易得到递推关系为 a[i+1]=2ai+bi    b[i+1]=2ai+2bi+2ci   c[i+1]=bi+2ci

发现n<=1e9 线性递推TLE 对于m项和递推式容易用矩阵来表示

(a[i+1],b[i+1],c[i+1])^T

=(2,1,0) (ai)

 (2,2,2) (bi)   //最终答案 a
只要(a0,b0,c0)^T*系数矩阵n次即可,即快速幂求出系数矩阵幂,复杂度为O(logn) 

 (0,1,2) (ci)


#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int mod=1e4+7;
typedef vector<int> vec;
typedef vector<vec> mat;// 二维matrix vec为列向量
typedef long long ll;
mat mul(mat A,mat B)
{
mat c(A.size(),vec(B[0].size()));
for(int i=0;i<A.size();i++)
{
for(int j=0;j<B[0].size();j++)//列
{
c[i][j]=0;
for(int k=0;k<B.size();k++)
{
c[i][j]=(c[i][j]+A[i][k]*B[k][j])%mod;
}
}
}
return c;
}
mat pow(mat A,ll n)
{
mat B(A.size(),vec(A.size()));//A^0
for(int i=0;i<A.size();i++)
B[i][i]=1;

while(n)
{
if(n&1)
B=mul(B,A);//二进制该位为1,则乘以基底

A=mul(A,A);
n>>=1;
}
return B;
}
int main()
{
int t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
mat A(3,vec(3));//3*3
A[0][0]=2;A[0][1]=1;A[0][2]=0;
A[1][0]=A[1][1]=A[1][2]=2;
A[2][0]=0;A[2][1]=1;A[2][2]=2;
A=pow(A,n);
//(a0,b0,c0)^T=(1,1,0)^T
//a
=A[0][0]
cout<<A[0][0]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: