Luogu P1939矩阵加速

Description:

a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。

Analysis:

[left[ egin{matrix} a_x \ a_{x-1}\a_{x-2} end{matrix} ight] = left[ egin{matrix} 1 & 0 & 1\ 1 & 0 & 0\0 & 1 & 0 end{matrix} ight] cdot left[ egin{matrix} a_{x-1} \ a_{x-2}\a_{x-3} end{matrix} ight] ]

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
const int mod = 1000000007;
using namespace std;
int n,T; 
struct Matrix{
	ll data[10][10];
	int r,c;
	Matrix(int R,int C)
	{
		r = R;
		c = C;
		memset(data,0,sizeof(data));
	}
	ll* operator [](int pos)
	{
		return data[pos];	
	}
	Matrix operator *(Matrix B)
	{
		Matrix C(r,B.c);
		for(int i = 1;i <= r;++i){
			for(int j = 1;j <= B.c;++j){
				for(int k = 1;k <= c;++k){
					C[i][j] = (C[i][j]%mod + (data[i][k]%mod)*(B[k][j]%mod)%mod)%mod;
				}
			}
		}
		return C;
	}
Matrix operator *(int b){
        Matrix B(R,C);
        for(int i = 1;i <= R;++i){
            for(int j = 1;j <= C;++j){
                B[i][j] = data[i][j]*b;
            }
        }
        return B;
    }
    Matrix T(){
        Matrix B(C,R);
        for(int i = 1;i <= C;++i){
            for(int j = 1;j <= R;++j){
                B[i][j] = data[j][i];
            }
        }
        return B;
    }
	void print(){
		for(int i = 1;i <= r;++i)
		{
			for(int j = 1;j <= c;++j)
			{
				printf("%lld ",data[i][j]);
			}
			puts("");
		}
	}
};
Matrix Pow(Matrix A,int b){
	Matrix res(A.r,A.c);
	for(int i = 1;i <= A.r;++i) res[i][i] = 1;//单位矩阵,相当于整数乘法中的1
	for(;b;b >>= 1){
		if(b&1) res = res*A;
		A = A*A;
	}
	return res;
}
int main()
{
	scanf("%d",&T);
	for(int i = 1;i <= T;++i){
		scanf("%d",&n);
		Matrix A(3,3);
		A[1][1] = A[1][3] = A[2][1] = A[3][2] = 1;
		if(n <= 3){
			printf("1
");
		} else {
			A = Pow(A,n-3);
			printf("%lld
",(A[1][1]%mod + A[1][2]%mod + A[1][3]%mod)%mod);
		}
	}
	return 0;
}

岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/10799157.html