P1939 矩阵加速

P1939 矩阵加速

已知一个数列 a,它满足:

ax={1x{1,2,3}ax1+ax3x4

a 数列的第 n 项对 109+7 取余的值。

  • 对于 100% 的数据 1T1001n2×109

我们发现 n2×109,这样我们就不能直接递推。

我们先构造答案矩阵,发现 ax=ax1+ax3,那么我们就需要把 ax,ax1,ax2 放进我们的答案矩阵。

[axax1ax2]

我们的目的是把他往前推一位,得到:

[ax+1axax1]

行和列对应,可以得到我们的转移矩阵:

[101100010]

那么我们只需要对开始的:

[111]

进行 n3 次转移即可得到答案。

code

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int MOD = 1e9 + 7;
const int MAXN = 105;
const int X = 3;
int n;
struct Matrix{
	int a[MAXN][MAXN];
	void tox(){
		for(int i = 1;i <= X;i++){
			for(int j = 1;j <= X;j++){
				a[i][j] = 0;
			}
		}
	}
	void unifyInit(){
		a[1][1] = 1,a[1][2] = 0,a[1][3] = 0;
		a[2][1] = 0,a[2][2] = 1,a[2][3] = 0;
		a[3][1] = 0,a[3][2] = 0,a[3][3] = 1;
	}
	void Init(){
		a[1][1] = 1,a[1][2] = 0,a[1][3] = 1;
		a[2][1] = 1,a[2][2] = 0,a[2][3] = 0;
		a[3][1] = 0,a[3][2] = 1,a[3][3] = 0;
	}
	void print() const{
		cout<<"-------------------------\n";
		for(int i = 1;i <= X;i++){
			for(int j = 1;j <= X;j++){
				cout<<a[i][j]<<" ";
			}
			cout<<endl;
		}
		cout<<"-------------------------\n";
	}
	Matrix operator*(const Matrix &other) const{
		Matrix ans;
		ans.tox();
		// print();
		// cout<<"***"<<endl;
		// other.print();
		for(int i = 1;i <= X;i++){
			for(int j = 1;j <= X;j++){
				for(int k = 1;k <= X;k++){
					ans.a[i][j] = (ans.a[i][j] + other.a[i][k] * a[k][j]) % MOD;
				}
			}
		}
		// cout<<"==="<<endl;
		// ans.print();
		return ans;
	}
	
};
Matrix qpow(Matrix x,int val){
	Matrix res;
	res.unifyInit();
	while(val){
		if(val & 1) res = res * x;
		x = x * x;
		val >>= 1;
	}
	return res;
}
Matrix m;
signed main(){
	int _;
	cin>>_;
	while(_--){
		int n;
		cin>>n;
		if(n == 1){
			cout<<1<<endl;
			continue;
		}else if(n == 2){
			cout<<1<<endl;
			continue;
		}else if(n == 3){
			cout<<1<<endl;
			continue;
		}
		m.Init();
		// m.print();
		m = qpow(m,n - 3);
		// m.print();
		int ans = 0;
		for(int i = 1;i <= X;i++){
			ans = (ans + m.a[1][i]) % MOD;
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @   wyl123ly  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示