洛谷p1939矩阵加速(矩阵快速幂)

洛谷p1939矩阵加速

链接:https://www.luogu.org/problemnew/show/P1939

题目描述
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入输出格式
输入格式:

第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。

输出格式:

每行输出一个非负整数表示答案。

输入输出样例
输入样例
3
6
8
10
输出样例
4
9
19

说明
对于30%的数据 n<=100;
对于60%的数据 n<=210^7;
对于100%的数据 T<=100,n<=2
10^9;

/*
由a[1]=a[2]=a[3]=1;
a[x]=a[x-3]+a[x-1]  (x>3)
    =a[x-1]*1+a[x-2]*0+a[x-3]*1
	
a[x-1]=a[x-1]*1+a[x-2]*0+a[x-3]*0;
a[x-2]=a[x-1]*0+a[x-2]*1+a[x-3]*0;

   所以单位矩阵就可以设置为
   1 0 1
   1 0 0
   0 1 0
   剩下的就是矩阵快速幂的模板
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
ll n;
struct mat{
	ll m[3][3];
}unit;
mat operator* (mat a, mat b){//重载乘号
	mat res;
	ll x;
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++){
			x = 0;
			for (int k = 0; k < 3; k++)
				x += (a.m[i][k] * b.m[k][j]) % mod;
			res.m[i][j] = x%mod;
		}
	return res;
}
void init_unit(){//初始化单位向量
	memset(unit.m, 0, sizeof unit.m);
	unit.m[0][0] = 1;
	unit.m[0][2] = 1;
	unit.m[1][0] = 1;
	unit.m[2][1] = 1;
}
mat pow_quick(ll n){//矩阵快速幂
	mat res=unit;
	if (n < 0) return res;
	while (n){
		if (n & 1) res = res*unit;
		unit = unit*unit;
		n >>= 1;
	}
	return res;
}
int main(){
	int t; cin >> t;
	while (t--){
		cin >> n;
		init_unit();
		mat res = pow_quick(n - 2);
		cout << res.m[0][0] * 1 << endl;
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值