hdu 2065

地址:http://acm.hdu.edu.cn/showproblem.php?pid=2065

题意:中文。

mark:很多人说是指数型母函数,的确指数型母函数可秒,但是出题者的意图更可能是考察递推+矩阵乘法。

按状态,长度为n的时候:D[1,n]表示偶数个A、偶数个C的情况数,D[2,n]表示偶数个A、奇数个C的情况数,D[3,n]表示奇数个A、偶数个C的情况数,D[4,n]表示奇数个A、奇数个C的情况数。有长度为n的时候情况可由长度为n-1的情况推来:(D[1,n],D[2,n],D[3,n],D[4,n])*M=(D[1,n+1],D[2,n+1],D[3,n+1],D[4,n+1])。其中M是一个矩阵,内容是{(2,1,1,0),(1,2,0,1),(1,0,2,1),(0,1,1,2)}。

之后就是矩阵乘法和快速幂了。注意长度n的范围应该是long long,否则要TLE。

代码:

# include <stdio.h>


int base[4][4] = {2,1,1,0,1,2,0,1,1,0,2,1,0,1,1,2} ;
int e[4][4] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} ;


void mul(int a[4][4], int b[4][4])
{
int ans[4][4] ;
int i, j, k ;
for(i=0;i<4;i++)for(j=0;j<4;j++)
ans[i][j] = 0 ;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
for(k=0;k<4;k++)
ans[i][j]=(ans[i][j]+a[i][k]*b[k][j]) % 100 ;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
a[i][j]=ans[i][j] ;
}


void qpow(int ans[4][4], long long n)
{
int i, j, buff[4][4] ;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
ans[i][j] = e[i][j], buff[i][j]=base[i][j] ;
while(n)
{
if(n&1) mul(ans,buff) ;
mul(buff, buff) ;
n>>=1 ;
}
}


int main ()
{
int T, nCase ;
long long n ;
int buff[4][4] ;

while (~scanf ("%d", &T), T)
{
nCase = 1 ;
while (T--)
{
scanf ("%I64d", &n) ;
qpow(buff, n) ;
printf ("Case %d: %d\n", nCase++, buff[0][0]) ;
}
printf ("\n") ;
}
return 0 ;
}



posted @ 2012-01-26 21:56  Seraph2012  阅读(601)  评论(0编辑  收藏  举报