zoukankan      html  css  js  c++  java
  • 矩阵快速幂

      矩阵快速幂的用途主要是用来递推公式。主要过程是构造一个系数矩阵A和一个值的矩阵B,令(A^k)×B的值与第k项正好相等或是相关。

    模板的话差不多都是一样的,只不过是把对数的快速幂拓展到了对矩阵的快速幂。这个模板里面用的是静态的矩阵,速度稍微会 快一点。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    #include <math.h>
    #define pi acos(-1.0 )
    #define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int INF = 0x3f3f3f3f;       // 不能加负号!!!
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
    const int maxn =100000 + 10;
    const LL mod = 2147493647;
    
    vector<LL> V;
    
    typedef struct MATRIX
    {
        LL mat[10][10];
    }MATRIX;
    
    MATRIX A, B;
    
    inline MATRIX mul(MATRIX a,MATRIX b,int n)
    {
        MATRIX c;
        memset(c.mat,0,sizeof(c.mat));
        for(int k=0;k<n;k++)
            for(int i=0;i<n;i++)
                if(a.mat[i][k])
                    for(int j=0;j<n;j++)
                        if(b.mat[k][j])
                        {
                            c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod;
                            c.mat[i][j]%=mod;
                        }
        return c;
    }
    inline MATRIX pow(MATRIX a,int N,int n)
    {
        MATRIX E;
        memset(E.mat,0,sizeof(E.mat));
        for(int i=0;i<n;i++) E.mat[i][i]=1;
        while(N>0)
        {
            if(N & 1)
                E=mul(E,a,n);
            N>>=1;
            a=mul(a,a,n);
        }
        return E;
    }
    
    void inn(int index , string s)
    {
        for(int i=0;i<s.length();i++){
            A.mat[index][i] = s[i]-'0';
        }
    }
    
    int main()
    {
        int T; scanf("%d", &T);
        while(T--){
            memset(A.mat, 0, sizeof(A.mat));
            memset(B.mat, 0, sizeof(B.mat));
            LL n, a, b;
            scanf("%lld%lld%lld", &n, &a, &b);
            string s;
            inn(0,"1210000");
            inn(1,"1000000");
            inn(2,"0014641");
            inn(3,"0001331");
            inn(4,"0000121");
            inn(5,"0000011");
            inn(6,"0000001");
    
            B.mat[0][0] = b;
            B.mat[1][0] = a;
            B.mat[2][0] = 81;
            B.mat[3][0] = 27;
            B.mat[4][0] = 9 ;
            B.mat[5][0] = 3 ;
            B.mat[6][0] = 1 ;
    
            if(n<=2){
                if(n==1) printf("%lld
    ",a);
                else printf("%lld
    ", b);
            }
            else {
                A = pow(A, n-2, 7);
                B = mul(A, B, 7);
                printf("%lld
    ", B.mat[0][0]);
            }
        }
    }
    View Code

    题目的链接:Recursive sequence

    主要的用法和技巧:

  • 相关阅读:
    【转】XP下安装IIS6.0的办法
    设计模式学习笔记十:单例模式(Singleton Pattern)
    linq学习笔记(2):DataContext
    设计模式学习笔记十二:桥接模式(Bridge Pattern)
    英文版c#数据结构
    linq学习笔记(3):Where
    一步步学习WCF(1):Hello
    linq学习笔记(5):Count/Sum/Min/Max/Avg
    [转]Asp.Net 面试题目收集
    从谷歌公司发现的十个至理名言
  • 原文地址:https://www.cnblogs.com/doggod/p/9742920.html
Copyright © 2011-2022 走看看