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;
}
题意 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;
}
相关文章推荐
- Poj 3734 Blocks(DP,矩阵乘法优化)
- POJ 3734 Blocks DP优化
- POJ 3734 Blocks(矩阵优化+DP)
- poj 3734 Blocks (矩阵快速幂优化的动态规划)
- poj 3734 Blocks
- POJ 3734 Blocks
- poj 3734 Blocks 组合计数
- [POJ 3734] Blocks (矩阵快速幂、组合数学)
- poj 3734 Blocks(构造矩阵加快速幂)
- Poj 3734 Blocks【矩阵快速幂+递推】
- POJ-3734-Blocks
- POJ 3734 Blocks
- POJ 3734 Blocks
- POJ 3734_Blocks
- POJ 3734_Blocks
- POJ 3734 Blocks (线性递推)
- poj 3734 Blocks
- POJ 3734 Blocks【用母函数推公式|矩阵乘法】
- POJ_3734_Blocks_矩阵快速幂
- 202——砖块染色问题 Blocks (POJ 3734)