矩阵快速幂
矩阵快速幂的用途主要是用来递推公式。主要过程是构造一个系数矩阵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\n",a); else printf("%lld\n", b); } else { A = pow(A, n-2, 7); B = mul(A, B, 7); printf("%lld\n", B.mat[0][0]); } } }
题目的链接:Recursive sequence
主要的用法和技巧: