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;
    }
  • 相关阅读:
    zkw费用流
    luogu5212/bzoj2555 substring(后缀自动机+动态树)
    后缀数据结构模板2
    后缀数据结构模板1
    通用动态树(Link-Cut Tree)模板
    上下界网络流总结
    多项式多点求值
    拉格朗日反演
    多项式板子·新
    luogu2387 [NOI2014]魔法森林
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9050887.html
Copyright © 2011-2022 走看看