《P1939 矩阵加速(数列)》

题目描述

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

ax​={1ax−1​+ax−3​​x∈{1,2,3}x≥4​

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

输入格式

第一行一个整数 T,表示询问个数。

以下 T 行,每行一个正整数 n。

输出格式

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

输入输出样例

输入 #1复制

复制代码
3
6
8
10

输出 #1复制

复制代码
4
9
19

说明/提示

  • 对于 30% 的数据 n≤100;
  • 对于 60% 的数据 n≤2×107;
  • 对于 100% 的数据 1≤T≤100,1≤n≤2×109。

代码实现:

cpp 复制代码
#include <cstdio> 
#include <iostream>  
using namespace std;
#define INF 1000000007
long long n, q[105];

struct mat{
	long long m[3][3];
	int sz;   
};

mat mul(mat a, mat b)
{
	mat res;
	for(int i=0;i<3;i++)
	  for(int j=0;j<3;j++)
	    res.m[i][j]=0;
	for(int i=0;i<3;i++)
	  for(int j=0;j<a.sz;j++)
	    for(int k=0;k<3;k++)
	      res.m[i][j]=((res.m[i][j]%INF)+(a.m[k][j]%INF)*(b.m[i][k]%INF))%INF;
	res.sz=a.sz;
	return res;
}

void qpow(long long x)
{
	mat t, ans;
	ans.sz=1;
	t.sz=3;
	ans.m[0][0]=ans.m[1][0]=ans.m[2][0]=1;
	for(int i=0;i<3;i++)
	  for(int j=0;j<3;j++) t.m[i][j]=0;
	t.m[0][0]=t.m[0][2]=t.m[1][0]=t.m[2][1]=1;
	while(x)
	{
		if(x&1) ans=mul(ans, t);
		t=mul(t, t);
		x>>=1;
	}
	cout<<ans.m[0][0]%INF<<endl;
}

int main()
{
	cin>>n;   
	for(int i=1;i<=n;i++)  
	cin>>q[i];   
	for(int i=1;i<=n;i++)
    {   
		if(q[i]<=3) {cout<<1<<endl;continue;}  
    qpow(q[i]-3);  
	} 
	return 0;
}
相关推荐
Jasmine_llq3 个月前
《P6772 [NOI2020] 美食家》
动态规划·状态压缩·矩阵快速幂·事件排序与分段处理·图论基础(图的表示与遍历)
惆怅客1233 个月前
UVa1497/LA5719 A Letter to Programmers
计算几何·icpc·uva·矩阵快速幂·三维变换矩阵
闻缺陷则喜何志丹8 个月前
【分治法 容斥原理 矩阵快速幂】P6692 出生点|普及+
c++·线性代数·数学·洛谷·容斥原理·分治法·矩阵快速幂
hnjzsyjyj1 年前
AcWing 3534:矩阵幂 ← 矩阵快速幂
矩阵快速幂