FZU1683 纪念SlingShot

Posted dlvguo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FZU1683 纪念SlingShot相关的知识,希望对你有一定的参考价值。

 Problem 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
 
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;

/* 矩阵快速幂问题,重点是找到矩阵
    Sn=Sn-1+f(n)=Sn-1+3*f(n-1)+2*f(n-2)+7*f(n-3)
    Base:Sn     | 1 1 0 0 | Sn-1
        f(n+1)  | 0 3 2 7 | f(n)
        f(n)    | 0 1 0 0 | f(n-1)
        f(n-1)  | 0 0 0 1 | f(n-2)

    Ori:S2    | 4 0 0 0 | 
        f(2)  | 5 0 0 0 | 
        f(1)  | 3 0 0 0 | 
        f(0)  | 1 0 0 0 | 
*/
struct Matrix
{
    int m[5][5];

    Matrix()
    {
        memset(m, 0, sizeof(m));
    }

    //初始化特征矩阵
    void init()
    {
        m[1][1] = 1;
        m[1][2] = 1;
        m[2][2] = 3;
        m[2][3] = 2;
        m[2][4] = 7;
        m[3][2] = 1;
        m[4][3] = 1;
    }

    //单位化
    void unit()
    {
        for (int i = 1; i <= 4; i++)
        {
            m[i][i] = 1;
        }
    }
};

//矩阵相乘
Matrix mul(Matrix a, Matrix b)
{
    Matrix c;
    for (int i = 1; i <= 4; i++)
    {
        for (int j = 1; j <= 4; j++)
        {
            for (int k = 1; k <= 4; k++)
            {
                c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % 2009;
            }
        }
    }
    return c;
}

//计算矩阵n次方
Matrix pow(int n)
{
    Matrix res;
    Matrix mt;
    mt.init();
    //化成单位矩阵
    res.unit();

    while (n)
    {
        if (n & 1)
            res = mul(res, mt);
        mt = mul(mt, mt);
        n = n >> 1;
    }
    return res;
}

int main()
{
    int m, n, c = 1, ans;
    cin >> m;
    //初始矩阵
    Matrix oriM;
    oriM.m[1][1] = 4;
    oriM.m[2][1] = 5;
    oriM.m[3][1] = 3;
    oriM.m[4][1] = 1;
    while (m--)
    {
        cin >> n;
        if (n == 0)
        {
            ans = 1;
        }
        else
        {
            Matrix p = mul(pow(n - 1), oriM);
            ans = p.m[1][1];
        }
        printf("Case %d: %d
", c++, ans);
    }
}

参考链接:https://blog.csdn.net/weixin_34221276/article/details/86129443

以上是关于FZU1683 纪念SlingShot的主要内容,如果未能解决你的问题,请参考以下文章

代码大全2中文纪念版与英文珍藏版区别

在通过 slingshot 上传之前使用 Meteor js 中的 Cropit 进行图像裁剪

一本通-P1683-稗田阿求

luogu4088 [USACO18FEB]Slingshot

P4088 [USACO18FEB]Slingshot 线段树+扫描线

1683 车厢重组