Problem 1683 纪念SlingShot
Accept: 682 Submit: 2368
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
第一行是一整数m,代表总共有m个cases。
Output
对于每个case,输出一行。格式见样例,冒号后有一个空格。
Sample Input
236
Sample Output
Case 1: 37
Case 2: 313
思路: 构造矩阵。矩阵的快速幂和矩阵的乘法, (注意两个矩阵相乘不满足交换律)
由此我们可以得到两个 矩阵 {1 3 2 7
0 3 2 7
0 1 0 0
0 0 1 0 }
{ 9 0 0 0
5 0 0 0
3 0 0 0
1 0 0 0 }
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define mod 2009
using namespace std;
struct node
{
int m[5][5];
};
node a,I;
int len=4;
void init()
{
I.m[1][1]=9;
I.m[2][1]=5;
I.m[3][1]=3;
I.m[4][1]=1;
a.m[1][1]=1;a.m[1][2]=3;a.m[1][3]=2;a.m[1][4]=7;
a.m[2][1]=0;a.m[2][2]=3;a.m[2][3]=2;a.m[2][4]=7;
a.m[3][1]=0;a.m[3][2]=1;a.m[3][3]=0;a.m[3][4]=0;
a.m[4][1]=0;a.m[4][2]=0;a.m[4][3]=1;a.m[4][4]=0;
return ;
}
node mut(node c,node b)
{
node ans;
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++){
ans.m[i][j]=0;
for(int k=1;k<=4;k++){
ans.m[i][j]=(ans.m[i][j]+b.m[i][k]*c.m[k][j])%mod;
}
}
}
return ans;
}
node solve(int kk)
{
node ans=I;
node aa=a;
while(kk)
{
if(kk&1){
ans=mut(ans,aa);
}
aa=mut(aa,aa);
kk/=2;
}
return ans;
}
int main()
{
init();
int t;
scanf("%d",&t);
int n;
int cas=0;
while(t--)
{
scanf("%d",&n);
printf("Case %d: ",++cas);
if(n<=2)
{
if(n==0) printf("1\n");
else if(n==1) printf("4\n");
else printf("10\n");
continue;
}
else
{
node fin = solve(n-2);
printf("%d\n",fin.m[1][1]%mod);
}
}
return 0;
}