P1939 【模板】矩阵加速(数列)

很明显珂以构造初始矩阵 \(f\)。
\begin{bmatrix}
1\\
1\\
1
\end{bmatrix}
状态矩阵
\begin{bmatrix}
f_{n-1}\\
f_{n-2}\\
f_{n-3}
\end{bmatrix}
转移矩阵构造:
由于
\begin{cases}
f_n=f_{n-1}+f_{n-3}\\
\\
f_{n-1}=f_{n-1}\\
\\
f_{n-2}=f_{n-2}
\end{cases}
可以构造矩阵 \(p\)
\begin{bmatrix}
1 & 0 & 1\\
1 & 0 & 0\\
0 & 1 & 0
\end{bmatrix}

然后答案=\(f\times p^{n-3}\) 的最上面一项

\(O((mnp)T\log n)=O(9T\log n)\),可以通过。

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct Matrix{
	int a[5][5];
	int n,m;
};
const int mod=1e9+7;
Matrix operator *(Matrix a,Matrix b){
	Matrix c;
	assert(a.m==b.n);
	c.n=a.n,c.m=b.m;
	for(int i=1;i<=c.n;i++){
		for(int j=1;j<=c.m;j++){
			int sum=0;
			for(int k=1;k<=a.m;k++)sum+=a.a[i][k]*b.a[k][j],sum%=mod;
			c.a[i][j]=sum;
		}
	}
	return c;
}
Matrix operator %(Matrix a,int b){
	for(int i=1;i<=a.n;i++){
		for(int j=1;j<=a.m;j++)a.a[i][j]%=b;
	}
	return a;
}
Matrix ksm(Matrix a,int b){
	if(b==1)return a;
	Matrix ans=ksm(a,b>>1);
	if(b&1)return ans*ans%mod*a%mod;
	else return ans*ans%mod;
}
Matrix f,p;
int T;
signed main(){
	f.n=3,f.m=1,f.a[1][1]=f.a[2][1]=f.a[3][1]=1;
	p.n=p.m=3;
	p.a[1][1]=1,p.a[1][2]=0,p.a[1][3]=1,p.a[2][1]=1,p.a[2][2]=0,p.a[2][3]=0,p.a[3][1]=0,p.a[3][2]=1,p.a[3][3]=0;
	cin>>T;
	while(T--){
		int n;
		cin>>n;
		if(n<=3)cout<<1<<endl;
		else cout<<(ksm(p,n-3)*f).a[1][1]<<endl;
	}
	return 0;
} 
上一篇:2021 杂题乱做


下一篇:LOJ #6208 树上询问