[Logo P1939] [Template] Matrix acceleration (number sequence) [Matrix multiplication]

Title description

l i n k link l i n k
Given a sequence a, it satisfies:
ax = 1 (x <= 1, 2, 3) a_x=1(x<=1,2,3)ax=1(x<=1,2,3)

a x = a x − 1 + a x − 3 ( x > = 4 ) a_x=a_{x-1}+a_{x-3}(x>=4) ax=ax1+ax3(x>=4 )
Requestaann of a sequencen item pairs1 0 9 + 7 10^9+7109+7 Take the remainder.

Input format

An integer TT in the first lineT represents the number of queries.
The followingTTT rows, each row has a positive integernnn

Output format

Each line outputs a non-negative integer to indicate the answer.

Sample input and output

Enter #1

3
6
8
10

Output #1

4
9
19

analysis:

The data is very large, consider matrix multiplication.
Let the initial matrix be [fi, fi − 1, fi − 2] [f_{i},f_{i-1},f_{i-2}][fi,fi1,fi2]
We want to multiply amatrixto transform it into[fi + 1, fi, fi − 1] [f_{i+1},f_{i},f_{i-1}][fi+1,fi,fi1]
The matrix can be deduced as:
1, 1, 0 1,1,01,1,0

0 , 0 , 1 0,0,1 0,0,1

1 , 0 , 0 1,0,0 1,0,0
f i f_i fiThere is the second digit to directly output matrix [1] [2] matrix[1][2]m A T R & lt I X [ . 1 ] [ 2 ] to

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const long long mod=1e9+7;
long long n;
int T; 
struct matrix{
    
    
	long long n,m;
	long long G[5][5];
}base,A,B;
matrix operator *(matrix a,matrix b)
{
    
    
	matrix C;
	C.n=a.n;C.m=b.m;
	for(int i=1;i<=C.n;i++)
		for(int j=1;j<=C.m;j++)
			C.G[i][j]=0;
	for(int k=1;k<=a.m;k++)
		for(int i=1;i<=a.n;i++)
			for(int j=1;j<=b.m;j++)
				C.G[i][j]=(C.G[i][j]+a.G[i][k]*b.G[k][j]%mod)%mod;  //矩阵乘法
	return C;
}
void ksm(long long x){
    
    
	if(x==1){
    
    
		A=base;
		return;
	}
	ksm(x/2);
	A=A*A;
	if(x&1) A=A*base;
}
int main(){
    
    
	scanf("%d",&T);
	while(T--)
	{
    
    
		scanf("%lld",&n);
		base.n=3;base.m=3;
		base.G[1][1]=1;base.G[1][2]=1;base.G[1][3]=0;
		base.G[2][1]=0;base.G[2][2]=0;base.G[2][3]=1;  //初始矩阵
		base.G[3][1]=1;base.G[3][2]=0;base.G[3][3]=0;
		if(n<=3){
    
    
			printf("1\n");
			continue;
		}
		else{
    
    
			B.m=2;B.n=1;
			B.G[1][1]=1;B.G[1][2]=1;
			ksm(n-1);
			B=B*A;
			printf("%lld\n",B.G[1][2]);
		}
	} 
	return 0;
}

Guess you like

Origin blog.csdn.net/dgssl_xhy/article/details/111240704