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 ;
}