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

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
int T;
LL n;

struct Matrix{
	LL h[5][5];
}a;

int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		Matrix ans,t;
		cin>>n;
		ans.h[1][1]=1; ans.h[1][2]=1; ans.h[1][3]=1;
		t.h[1][1]=1; t.h[1][2]=1; t.h[1][3]=0;
		t.h[2][1]=0; t.h[2][2]=0; t.h[2][3]=1;
		t.h[3][1]=1; t.h[3][2]=0; t.h[3][3]=0;
		for(n-=3;n>0;n>>=1){
			if(n&1){
				Matrix x;
				for(int i=1;i<=3;i++){
					LL sum=0;
					for(int j=1;j<=3;j++)sum+=ans.h[1][j]*t.h[j][i],sum%=mod;
					x.h[1][i]=sum;
				}
				for(int i=1;i<=3;i++)ans.h[1][i]=x.h[1][i];
			}
			Matrix d;
			for(int i=1;i<=3;i++)
				for(int j=1;j<=3;j++){
					LL sum=0;
					for(int k=1;k<=3;k++)sum+=t.h[i][k]*t.h[k][j],sum%=mod;
					d.h[i][j]=sum;
				}
			for(int i=1;i<=3;i++)
				for(int j=1;j<=3;j++)t.h[i][j]=d.h[i][j];
		}
		cout<<ans.h[1][1]<<endl;
	}
	return 0;
}

  //结构体函数版:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
int T;
LL n;

struct Matrix{
	LL h[5][5];
	void clear(){
		memset(h,0,sizeof(h));
	}
	Matrix operator * (const Matrix& t) const{
		Matrix d; d.clear();
		for(int i=1;i<=3;i++)
			for(int j=1;j<=3;j++){
				LL sum=0;
				for(int k=1;k<=3;k++)sum+=h[i][k]*t.h[k][j],sum%=mod;
				d.h[i][j]=sum;
			}
		return d;
	}
	Matrix operator ^ (LL k) const {
		Matrix ans(*this),t(*this),x(*this);
		t.clear();
		t.h[1][1]=1; t.h[1][2]=1; t.h[1][3]=0;
		t.h[2][1]=0; t.h[2][2]=0; t.h[2][3]=1;
		t.h[3][1]=1; t.h[3][2]=0; t.h[3][3]=0;
		for(k-=3;k>0;k>>=1){
			if(k&1)
				for(int i=1;i<=3;i++){
					LL sum=0;
					for(int j=1;j<=3;j++)sum+=ans.h[1][j]*t.h[j][i],sum%=mod;
					x.h[1][i]=sum;
				}
			for(int i=1;i<=3;i++)ans.h[1][i]=x.h[1][i];
			t=t*t;
		}
		return ans;
	}
}a;

int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		Matrix ans,t;
		cin>>n;
		ans.h[1][1]=1; ans.h[1][2]=1; ans.h[1][3]=1;
		t.h[1][1]=1; t.h[1][2]=1; t.h[1][3]=0;
		t.h[2][1]=0; t.h[2][2]=0; t.h[2][3]=1;
		t.h[3][1]=1; t.h[3][2]=0; t.h[3][3]=0;
		ans=ans^n;
		cout<<ans.h[1][1]<<endl;
	}
	return 0;
}

  

时间: 2024-10-29 19:08:01

luogu_1939 【模板】矩阵加速(数列)的相关文章

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

链接: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. 输出格式: 每行输出一个非负整数表示答案. 输入输出样例 输入样例#1: 3 6 8 10 输出样例#1: 4 9 19 说明 对于30%的数据 n<=100: 对于60%的数据 n<=2*10^7

斐波那契数列F(n)【n超大时的(矩阵加速运算) 模板】

hihocoder #1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示

[LGOJ]P1939【模板】矩阵加速(数列)[矩阵加速递推]

题面 矩阵加速递推的原理: 首先你得会矩阵乘法与快速幂. 以斐波拉契数列为例, 要从矩阵A \[ \begin{bmatrix} f[n-1] & f[n]  \end{bmatrix} \] 得到矩阵B \[ \begin{bmatrix} f[n] & f[n+1]  \end{bmatrix} \] 显然可以\[\begin{bmatrix} f[n-1] & f[n] \end{bmatrix}\times \begin{bmatrix}  0 & 1\\ 1 &a

【矩阵加速】 矩阵 快速幂

矩阵的快速幂是用来高效地计算矩阵的高次方的.将朴素的o(n)的时间复杂度,降到log(n). 这里先对原理(主要运用了矩阵乘法的结合律)做下简单形象的介绍: 一般一个矩阵的n次方,我们会通过连乘n-1次来得到它的n次幂. 但做下简单的改进就能减少连乘的次数,方法如下: 把n个矩阵进行两两分组,比如:A*A*A*A*A*A => (A*A)*(A*A)*(A*A) 这样变的好处是,你只需要计算一次A*A,然后将结果(A*A)连乘自己两次就能得到A^6,即(A*A)^3=A^6.算一下发现这次一共乘

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

【HDU3802】【降幂大法+矩阵加速+特征方程】Ipad,IPhone

Problem Description In ACM_DIY, there is one master called “Lost”. As we know he is a “-2Dai”, which means he has a lot of money.  Well, Lost use Ipad and IPhone to reward the ones who solve the following problem.  In this problem, we define F( n ) a

递推&#183;矩阵加速

这个题其实很简单,简单分析一下规律,发现发f[i]=f[i-1]+f[i-2]. 如下图: 程序: 1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int n,i,j,a[101]; 6 cin>>n; 7 a[1]=1;a[2]=2; 8 for (i=3;i<=n;i++) 9 { 10 a[i]=a[i-1]+a[i-2]; 11 } 12 cout<<a[n]; 13 } 用这个

矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

HDU 5564 Clarke and digits 状压dp+矩阵加速

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5564 题意: 求长度在[L,R]范围,并且能整除7的整数的总数. 题解: 考虑最原始的想法: dp[i][j][k]表示长度为i,并且对7取模得到j的以k结尾的数. 则有状态转移方程dp[i+1][(h*10)+l)%7][k]+=dp[i][h][k'](k+k'!=K). 但是i范围是1~10^9,需要矩阵加速. 这里对dp[i][j][k]的[j][k]两个状态进行压缩,得到转移矩阵mat[

POJ3420 Quad Tiling (矩阵加速状压dp)

传送门:http://poj.org/problem?id=3420 Quad Tiling Time Limit: 1000MS   Memory Limit: 65536K       Description Tired of the Tri Tiling game finally, Michael turns to a more challengeable game, Quad Tiling: In how many ways can you tile a 4 × N (1 ≤ N ≤ 1