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



 纪念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

2
3
6

Sample Output

Case 1: 37
Case 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值