Problem 1683 纪念SlingShot
Accept: 719 Submit: 2492
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
第一行是一整数m,代表总共有m个cases。
Output
对于每个case,输出一行。格式见样例,冒号后有一个空格。
Sample Input
236
Sample Output
Case 1: 37Case 2: 313
矩阵不能开太大,卡了memset的时间。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#define max_ 200010
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
struct mat
{
ll num[5][5];
int n;
};
int m,n,k;
int cas=0;
mat mul(struct mat a,struct mat b)
{
struct mat ans;
ans.n=a.n;
memset(ans.num,0,sizeof(ans.num));
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
ans.num[i][j] = (a.num[i][4]*b.num[4][j] + a.num[i][1]*b.num[1][j]
+ a.num[i][2]*b.num[2][j] + a.num[i][3]*b.num[3][j]) % 2009;
}
}
return ans;
}
void show(struct mat a)
{
printf("%d\n",a.n);
for(int i=1;i<=a.n;i++)
{
for(int j=1;j<=a.n;j++)
{
printf("%d ",a.num[i][j]);
}
printf("\n" );
}
}
int fpow(struct mat a,int k)
{
struct mat ans,tmp=a;
ans.n=a.n;
memset(ans.num,0,sizeof(ans.num));
for(int i=1;i<=4;i++)
ans.num[i][i]=1;
while(k!=0)
{
if(k&1)
ans=mul(ans,tmp);
tmp=mul(tmp,tmp);
k/=2;
}
int sum=0;
sum=(ans.num[1][1]*9+ans.num[1][2]*5+ans.num[1][3]*3+ans.num[1][4])%2009;
return sum;
}
int main(int argc, char const *argv[]) {
int t;
cin>>t;
mat a;
memset(a.num,0,sizeof(a.num));
a.n=4;
a.num[1][1]=1;
a.num[1][2]=3;
a.num[1][3]=2;
a.num[1][4]=7;
a.num[2][2]=3;
a.num[2][3]=2;
a.num[2][4]=7;
a.num[3][2]=1;
a.num[4][3]=1;
while(t--)
{
cin>>n;
if(n==0)
{
printf("Case %d: 1\n",++cas );
continue;
}
else if(n==1)
{
printf("Case %d: 4\n",++cas );
continue;
}
else if(n==2)
{
printf("Case %d: 9\n",++cas );
continue;
}
else if(n==3)
{
printf("Case %d: 28\n",++cas );
continue;
}
printf("Case %d: %d\n",++cas,fpow(a,n-2));
}
return 0;
}