您的位置:首页 > 其它

poj 3734 Blocks

2014-09-29 18:52 218 查看
从左边开始染色,到第$i$个方块为止,红绿都是偶数的方案数为$a_i$,红绿恰有一个是偶数的方案为$b_i$,红绿都是奇数的方案为$c_i$,从而有如下状态转移方程:

$a_{i+1} = 2 \times a_i + b_i$

$b_{i+1} = 2 \times a_i + 2 \times b_i + 2 \times c_i$

$c_{i+1} = b_i + 2 \times c_i$

从而可以用矩阵表示:

\begin{equation} \left( \begin{array}{c} a_i \\ b_i \\ c_i \end{array} \right) = \left( \begin{array}{ccc} 2 & 1 & 0 \\ 2 & 2 & 2 \\ 0 & 1 & 2 \end{array} \right)^i \left( \begin{array}{c} 1\\ 0\\ 0\\ \end{array} \right) \end{equation}

最终使用矩阵的快速幂即可求解。

#define     MOD 10007
#define     M 3
#include  <cstdio>
#include  <cstdlib>
#include  <iostream>
#include  <cstring>
int N;
using namespace std;
class Matrix
{
public:
int a[M][M];
Matrix(bool init = 0)
{
memset(a, 0, sizeof(a));
if( init == 1 )
{
for( int i = 0 ; i < M ; i++ )
{
a[i][i] = 1;
}
}
}
int * operator [](int i)
{
return a[i];
}
const int * operator [](int i)const
{
return a[i];
}
};
Matrix A;
void add(int &a, int b)
{
a += b;
while( a >= MOD )
{
a -= MOD;
}
}
Matrix operator * (const Matrix &a, const Matrix &b)
{
Matrix c;
for( int i = 0 ; i < M ; i++ )
{
for( int j = 0 ; j < M ; j++ )
{
for( int k = 0 ; k < M ; k++ )
{
add(c[i][k], 1ll * a[i][j] * b[j][k] %MOD);
}
}
}
return c;
}
Matrix quick_pow(Matrix m, int n)
{
Matrix ans(1);
while( n )
{
if( n & 1 )
{
ans = ans * m;
}
n = n>>1;
m = m * m;
}
return ans;
}
void solve()
{
Matrix ans;
ans = quick_pow(A, N);
printf ( "%d\n", ans[0][0]);
}
int main(int argc, char *argv[])
{
int T;
scanf ( "%d", &T );
A[0][0] = 2, A[0][1] = 1;
A[1][0] = 2, A[1][1] = 2, A[1][2] = 2;
A[2][1] = 1, A[2][2] = 2;
while( T-- )
{
scanf ( "%d", &N );
solve();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: