题目地址:FZU 1683
这题一开始用的二分矩阵,于是就一直TLE。后来找题解才发现,可以不用二分矩阵,因为这个题最终求的是一个值,所以可以把那个值加入到构造的矩阵中:
这样就不用二分矩阵了。而是可以直接求。但是这样还是会超时,那怎么办呢。由于本题的模数是固定的,所以矩阵的幂也是固定的。那么就可以对一些2^x幂预处理出来。
代码如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
const int mod =2009;
struct matrix
{
int ma[5][5];
} init, res, mat[40];
matrix Mult(matrix x, matrix y)
{
matrix tmp;
int i, j, k;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
tmp.ma[i][j]=0;
for(k=0; k<4; k++)
{
tmp.ma[i][j]=(tmp.ma[i][j]+x.ma[i][k]*y.ma[k][j])%mod;
}
}
}
return tmp;
}
matrix Pow(matrix x, int k)
{
int i, j, cnt=0;
//for(i=0; i<4; i++) for(j=0; j<4; j++) tmp.ma[i][j]=(i==j);
while(k)
{
if(k&1) x=Mult(mat[cnt],x);
k>>=1;
cnt++;
}
return x;
}
void per()
{
int i;
mat[0]=init;
for(i=1; i<32; i++)
{
mat[i]=Mult(mat[i-1],mat[i-1]);
}
}
int main()
{
int t, i, j, k, num=0;
scanf("%d",&t);
memset(init.ma,0,sizeof(init.ma));
init.ma[0][0]=init.ma[0][1]=init.ma[2][1]=init.ma[3][2]=1;
init.ma[1][1]=3;
init.ma[1][2]=2;
init.ma[1][3]=7;
per();
while(t--)
{
num++;
scanf("%d",&k);
printf("Case %d: ",num);
if(k==0) puts("1");
else if(k==1) puts("4");
else
{
res=Pow(init,k-1);
int ans=res.ma[0][0]*4+res.ma[0][1]*5+res.ma[0][2]*3+res.ma[0][3];
ans%=mod;
printf("%d\n",ans);
}
}
return 0;
}
原文地址:http://blog.csdn.net/scf0920/article/details/39502437