// 开始想的是RGBY,4x4...结果发现进行不下去
// 原来是简单的计数就好,分类讨论
// A:同偶
// B:单偶
// C:无偶
// 那么从第i个格子,到第i+1个格子涂色的话
// A(i+1) 2 1 0 A(i)
// B(i+1) = 2 2 2 x B(i)
// C(i+1) 0 1 2 C(i)
//
// 简单来说:
// 对于同偶A(i+1) 有三种情况
// 之前是同偶的情况,那由第i+1个格子刷其他两种无关颜色 即2*A(i)
// 之前是单偶只能将第i+1个格子刷成红绿中的单数的那个颜色,变成偶数 即B(i)
// 而无偶无法通过刷第i+1个格子得到
//
// 对于单偶B(i+1) 同样:
// 之前是同偶的情况 任意刷红绿即可变为单偶 即:2*A(i)
// 之前是单偶 刷其他两种无关颜色 即:2*B(i)
// 无偶 刷红绿其中之一 即:2*C(i)
//
// 对于无偶C(i+1) 同样:
// 之前是同偶的情况 无法完成
// 之前是单偶 将第i+1个格子刷成红绿中的偶数的颜色 即:B(i)
// 之前是无偶 刷两种不相关的颜色 即:2 * C(i)
//
// 想一下还是觉得可做的,继续加油吧~~~~
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MOD = 10007;
struct Matrix{
int a[4][4];
}M;
Matrix Mul(Matrix a,Matrix b){
Matrix c;
memset(c.a,0,sizeof(c.a));
for (int i = 1;i <= 3; i ++){
for (int k = 1;k <= 3; k ++){
for (int j = 1;j <= 3;j ++){
c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j]) % MOD;
}
}
}
return c;
}
void print(Matrix &a){
for (int i = 1;i <= 3;i ++){
for (int j= 1;j <= 3;j ++){
printf("%d ",a.a[i][j]);
}
cout << endl;
}
}
void Pow(Matrix a,int n){
Matrix res;
memset(res.a,0,sizeof(res.a));
res.a[1][1] = res.a[2][2] = res.a[3][3] = 1;
while(n){
if (n & 1) res = Mul(res,a);
a = Mul(a,a);
n >>= 1;
}
printf("%d\n",res.a[1][1]);
}
int main(){
int n;
int T;
// freopen("1.txt","r",stdin);
scanf("%d",&T);
M.a[1][1] = 2; M.a[1][2] = 1; M.a[1][3] = 0;
M.a[2][1] = 2; M.a[2][2] = 2; M.a[2][3] = 2;
M.a[3][1] = 0; M.a[3][2] = 1; M.a[3][3] = 2;
while(T--){
scanf("%d",&n);
Pow(M,n);
}
return 0;
}
poj 3734 简单快速幂
最新推荐文章于 2020-04-27 18:59:46 发布