Accept: 564 Submit: 1975
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
第一行是一整数m,代表总共有m个cases。
Output
对于每个case,输出一行。格式见样例,冒号后有一个空格。
Sample Input
2
3
6
Sample Output
Case 1: 37
Case 2: 313
分析:
学会矩阵的构造方法就很容易做这种题目了,尤其是这种线性的递推式,很容易的。。。
矩阵:1 3 2 7
0 3 2 7
0 1 0 0
0 0 1 0
分享一个不错的如何构造矩阵的学习链接,看了以后这种题目就基本差不多会了!
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long int ll;
const int mod = 2009;
struct matrix{
int a[4][4];
matrix operator*(const matrix& tmp){
matrix ans;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++){
ans.a[i][j] = 0;
for(int k=0; k<4; k++)
ans.a[i][j] = (ans.a[i][j] + a[i][k]*tmp.a[k][j])%mod;
}
return ans;
}
};
matrix quick_pow(matrix a,ll n){
matrix ans;
memset(ans.a,0,sizeof(ans.a));
for(int i=0; i<4; i++)
ans.a[i][i] = 1;
while(n){
if(n%2)
ans = ans*a;
a = a*a;
n /= 2;
}
return ans;
}
int main(){
matrix m;
ll N;
int T;
scanf("%d",&T);
int Case = 0;
while(T--){
scanf("%I64d",&N);
if(N==0){
printf("Case %d: 1\n",++Case);
continue;
}
else if(N==1){
printf("Case %d: 4\n",++Case);
continue;
}
else if(N==2){
printf("Case %d: 9\n",++Case);
continue;
}
memset(m.a,0,sizeof(m.a));
m.a[0][0] = 1;
m.a[0][1] = 3;
m.a[0][2] = 2;
m.a[0][3] = 7;
m.a[1][1] = 3;
m.a[1][2] = 2;
m.a[1][3] = 7;
m.a[2][1] = 1;
m.a[3][2] = 1;
matrix ans = quick_pow(m,N-2);
ll hehe = (ans.a[0][0]*9+ans.a[0][1]*5+ans.a[0][2]*3+ans.a[0][3])%mod;
printf("Case %d: %I64d\n",++Case,hehe);
}
return 0;
}