• NYOJ——301递推求值(矩阵快速幂)


    递推求值
    时间限制:1000 ms | 内存限制:65535 KB
    难度:4
    描述
    给你一个递推公式:

    f(x)=a*f(x-2)+b*f(x-1)+c

    并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。

    注意:-1对3取模后等于2

    输入
    第一行是一个整数T,表示测试数据的组数(T<=10000)
    随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
    其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)
    输出
    输出f(n)对1000007取模后的值
    样例输入
    2
    1 1 1 1 0 5
    1 1 -1 -10 -100 3
    样例输出
    5
    999896

    之前一直玩二维的,发现三维的矩阵也蛮容易构造的。新编辑器蛮好用。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    typedef long long LL;
    #define INF 0x3f3f3f3f
    const LL mod=1000007;
    struct mat
    {
        LL pos[3][3];
        mat(){memset(pos,0,sizeof(pos));}
    };
    inline mat operator*(const mat &a,const mat &b)
    {
        int i,j,k;
        mat c;
        for (i=0; i<3; i++)
        {
            for (j=0; j<3; j++)
            {
                for (k=0; k<3; k++)
                {
                    c.pos[i][j]+=(((a.pos[i][k])%mod)*(b.pos[k][j])%mod+mod)%mod;
                }
            }
        }
        return c;
    }
    inline mat matpow(mat a,LL b)
    {
        mat r,bas;
        r.pos[0][0]=r.pos[1][1]=r.pos[2][2]=1;
        bas=a;
        while (b!=0)
        {
            if(b&1)
                r=r*bas;
            bas=bas*bas;
            b>>=1;
        }
        return r;
    }
    int main(void)
    {
        ios::sync_with_stdio(false);
        LL a,b,c,n,f1,f2;
        int tcase;
        while (cin>>tcase)
        {
            while (tcase--)
            {
                cin>>f1>>f2>>a>>b>>c>>n;
                if(n==1)
                    cout<<f1<<endl;
                else if(n==2)
                    cout<<f2<<endl;
                else
                {
                    mat t,one;
                    t.pos[0][0]=b,t.pos[0][1]=a,t.pos[0][2]=c;
                    t.pos[1][0]=t.pos[2][2]=1;
                    one.pos[0][0]=f2,one.pos[1][0]=f1,one.pos[2][0]=1;
                    t=matpow(t,n-2);
                    one=t*one;
                    cout<<one.pos[0][0]%mod<<endl;
                }   
            }       
        }
        return 0;
    }
  • 相关阅读:
    git 知道这些就够了
    接私活可用的 Springboot + Vue 快速开发框架
    Vue 组件传值
    Vue实现点击按钮复制功能
    vue 获取组件高度
    git commit 提交的时候报错husky > pre-commit hook failed (add --no-verify to bypass)(解决办法)
    vue中异步函数async和await的用法
    JS设置浏览器缩放比例
    CSS修改滚动条的样式
    JS代码查看浏览器页面放大比例
  • 原文地址:https://www.cnblogs.com/Blackops/p/5766386.html
Copyright © 2020-2023  润新知