zoukankan      html  css  js  c++  java
  • 洛谷P1939【模板】矩阵加速(数列)+矩阵快速幂

    思路:

    这个

    a[1]=a[2]=a[3]=1

    a[x]=a[x-3]+a[x-1] (x>3)

    可以想成:

    a(n)  】  【1 0 1】 【a(n-1)   】

    a(n-1) 】 =   【1 0 0】 * 【a(n-2)  】

    a(n-2) 】   【0 1 0】 【a(n-3)   】

    然后就是利用矩阵快速幂去算中间那个矩阵的n次结果

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    typedef long long ll;
    const int lg= 1e9+7;
    const int maxn = 4;
    struct node {
        ll m[maxn][maxn];
    }ans,res;
    
    node Mul(node a,node b,ll n)
    {
        node tmp;
        memset(tmp.m,0,sizeof(tmp));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                for(int k=1; k<=n; k++)
                    tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j]%lg)%lg;
            }
        }
        return tmp;
    }
    void jzksm(ll n,ll k)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)ans.m[i][j] = 1;
                else ans.m[i][j] = 0;
            }
        }
        while(k)
        {
            if(k&1)ans = Mul(ans,res,n);
            res = Mul(res,res,n);
            k>>=1;
        }
    }
    int main(){
        int t,n;
        scanf("%d", &t);
        while(t--)
        {
    
    
            scanf("%d", &n);
            memset(res.m,0,sizeof(res.m));
            res.m[1][1] = res.m[1][3] = res.m[2][1] = res.m[3][2] = 1;
            jzksm(3,n);
            printf("%lld
    ",ans.m[2][1]%lg);
            
    
        }
        return 0;
    }
  • 相关阅读:
    递推数列
    大数阶乘
    成绩排序
    DevC++ return 1 exit status
    POJ 1061 青蛙的约会
    ZOJ 2750 Idiomatic Phrases Game
    nyoj 545 Metric Matrice
    nyoj 308 Substring
    nyoj 515完全覆盖 II
    nyoj 1248 海岛争霸
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9050887.html
Copyright © 2011-2022 走看看