• Final Destination II -- 矩阵快速幂模板题


    求f[n]=f[n-1]+f[n-2]+f[n-3]

    我们知道

    f[n] f[n-1] f[n-2]         f[n-1]  f[n-2]  f[n-3]         1    1     0     

    0     0       0         =    0          0         0     *      1    0     1

    0     0       0               0           0        0            1     0     0

    矩阵快速幂就是利用快速幂的思路,去加速转移矩阵的计算,从而给计算带来方便

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define LL long long
    using namespace std;
    const LL mod = 1e9+7;
    struct M
    {
        LL a[3][3];
        void init()
        {
            memset(a, 0, sizeof(a));
            a[0][0]=1;
            a[1][1]=1;
            a[2][2]=1;
        }
        void init0(){
        memset(a, 0, sizeof(a));
        }
    };
    M mul (M a,M b)
    {
        M ans;
        for (int i=0; i<3; i++)
        {
            for (int j=0; j<3; j++)
            {
                ans.a[i][j]=0;
                for (int k=0; k<3; k++)
                {
                    ans.a[i][j]+=a.a[i][k]*b.a[k][j];
                    ans.a[i][j]%=mod;
                }
            }
        }
        return ans;
    }
    M qpow(M a,LL n)
    {
        M ans;
        ans.init();
        while(n)
        {
            if (n&1)ans=mul(ans,a);
            a=mul(a,a);
            n/=2;
        }
        return ans;
    }
    void output(M a)
    {
        for(int i=0; i<3; ++i)
        {
            for(int j=0; j<3; ++j)
            {
                cout << a.a[i][j] << " ";
            }
            cout << endl;
        }
    }
    int main()
    {
        int n;
        int t;
        int num=0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            num++;
            M a,b;
            a.a[0][0]=1;
            a.a[0][1]=1;
            a.a[0][2]=0;
            a.a[1][0]=1;
            a.a[1][1]=0;
            a.a[1][2]=1;
            a.a[2][0]=1;
            a.a[2][1]=0;
            a.a[2][2]=0;
             //   output(a);
                M k=qpow(a,n);
    //            output(a);
    //            cout<<endl;
                printf("Case %d:
    ",num);
                printf("%lld
    ",k.a[0][0]);
        }
        return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    用带缓冲区的文件流FileStream来实现大文件的拷贝
    委托与事件、匿名方法与Lambda表达式
    C#基础点记录
    C#基础知识06
    用while语句实现用户登陆程序
    TSQL检索电话呼叫员的工作流水信息
    委托
    类型转换、异常、String知识总结
    内网入库单管理系统
    用C#打印出正等腰三角形
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/9853748.html
Copyright © 2020-2023  润新知