FZU 1683纪念SlingShot (简单的矩阵快速幂)

来源:互联网 发布:sql语句美化小工具 编辑:程序博客网 时间:2024/06/06 18:52



 纪念SlingShot

Description

已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给定的每个n,输出F(0)+ F(1)+ …… + F(n) mod 2009。

Input

第一行是一整数m,代表总共有m个cases。

Output

对于每个case,输出一行。格式见样例,冒号后有一个空格。

Sample Input

236

Sample Output

Case 1: 37Case 2: 313

思路:很简单的矩阵推理。。 告诉了 fn-1,fn-2,fn-3所以因子里面肯定有这三个,同时他是求和,所以因子里面肯定有个sn,直接列上就出答案了。。。


S(n)=S(n-1)+F(n)=S(n-1)+3F(n-1)+2F(n-2)+7F(n-3),因此构造矩


阵:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MOD = 2009;int n;struct node{    int matrix[4][4];};node mul(node a, node b){    node t;    memset(t.matrix, 0, sizeof(t.matrix));    for(int i = 0; i < 4; i++)        for(int j = 0; j < 4; j++)            for(int k = 0; k < 4; k++)                t.matrix[i][j] = (t.matrix[i][j] + a.matrix[i][k] * b.matrix[k][j]) % MOD;    return t;}node quick_matrix(node p, int k){    node q;    memset(q.matrix, 0, sizeof(q.matrix));    for(int i = 0; i < 4; i++)        q.matrix[i][i] = 1;    while(k)    {        if(k & 1) q = mul(p, q);        p = mul(p, p);        k >>= 1;    }    return q;}int main(){    int t, l = 0;    scanf("%d", &t);    while(t--)    {        scanf("%d", &n);        node r;        r.matrix[0][0] = 1; r.matrix[0][1] = 3; r.matrix[0][2] = 2; r.matrix[0][3] = 7;        r.matrix[1][0] = 0; r.matrix[1][1] = 3; r.matrix[1][2] = 2; r.matrix[1][3] = 7;        r.matrix[2][0] = 0; r.matrix[2][1] = 1; r.matrix[2][2] = 0; r.matrix[2][3] = 0;        r.matrix[3][0] = 0; r.matrix[3][1] = 0; r.matrix[3][2] = 1; r.matrix[3][3] = 0;        if(n == 0)  {printf("Case %d: 1\n",++l); continue;}        if(n == 1)  {printf("Case %d: 4\n",++l); continue;}        r = quick_matrix(r, n-2);        printf("Case %d: %d\n",++l, (r.matrix[0][0]*9 + r.matrix[0][1]* 5 + r.matrix[0][2] * 3 + r.matrix[0][3])% MOD);    }    return 0;}



2 0