您的位置:首页 > 其它

【poj3734】矩阵乘法

2015-09-19 07:39 489 查看
题解:

若当前有i个格子。
2个是偶数的方案数为a[i]
1个是偶数的方案数为b[i]
0个是偶数的方案数为c[i]

a[i+1]=2*a[i](i+1染成黄或蓝)+b[i](把奇数变为偶数)
b[i+1]=2*a[i](把某个偶数变为奇数)+2*b[i](i+1染成黄或蓝)+2*c[i](把某个奇数变为偶数)
c[i+1]=b[i](把偶数变为奇数)+2*c[i](i+1染成黄或蓝)

解析式难想,要学会这种分类递推的方法。

然后就可以推出

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;

const int N=1000000010,Mod=10007;

struct node{
int sx,sy;
int s[4][4];
};

node mult(node a,node b)
{
node c;
c.sx=a.sx;c.sy=b.sy;
memset(c.s,0,sizeof(c.s));
for(int i=1;i<=a.sx;i++)
for(int j=1;j<=b.sy;j++)
for(int k=1;k<=a.sx;k++)
{
c.s[i][j]+=(a.s[i][k]*b.s[k][j])%Mod;
c.s[i][j]%=Mod;
}
return c;
}

void solve(int x)
{
node a;
a.sx=a.sy=3;
a.s[1][1]=2;a.s[1][2]=1;a.s[1][3]=0;
a.s[2][1]=a.s[2][2]=a.s[2][3]=2;
a.s[3][1]=0;a.s[3][2]=1;a.s[3][3]=2;
node b;
b.sx=b.sy=3;
memset(b.s,0,sizeof(b.s));
for(int i=1;i<=3;i++) b.s[i][i]=1;
while(x)
{
if(x&1) b=mult(b,a);
a=mult(a,a);
x>>=1;
}
node c;
c.sx=3;c.sy=1;
c.s[1][1]=1;
c.s[2][1]=c.s[3][1]=0;
c=mult(b,c);

printf("%d\n",c.s[1][1]);
return ;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x;
scanf("%d",&x);
solve(x);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: