1009 - 矩阵快速幂

版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 https://blog.csdn.net/weixin_42557561/article/details/82989177

矩阵快速幂

描述

一个数列定义如下: f(1) = 1, f(2) = 1, f(n) = (A f(n - 1) + B f(n - 2)) mod 30013。给定 A,B 和 n 的值,要求计算 f(n)的值。

输入

仅一行包含 3 个整数 A, B 和 n

输出

仅一行,一个整数,即 f(n) %30013的值。

样例输入

1 1 3

样例输出

2

提示

【数据规模】 20%的数据, n≤1,000 40%的数据, n≤100,000 100%的数据, n≤100,000,000 150%的数据,1<=10^18

Before reading,let's have a quick review about the quickpower of matrix

  1. 两个矩阵可以相乘的前提条件是,A矩阵的列数=B矩阵的行数
  2. 矩阵乘法不满足交换律,但满足结合律

分析

这个数据规模写得很鬼畜啊……搞得我都忘了开long long,wa了两次。我还以为那个150%是过来凑热闹的,结果就gg了

话说150%的数据是什么意思啊?求大佬帮看

说回这道题,就是稍微推一下矩阵的方程,然后快速幂乱搞一下

推的时候傻逼了一下,两个矩阵相乘只要A矩阵的列数=B矩阵的行数就行了

最后推出来的方程就是

\begin{bmatrix} f[i] & f[i-1] \end{bmatrix}*\begin{bmatrix} A & 1\\ B&0 \end{bmatrix}

然后为了方便矩阵快速幂,我们把第一个弄成方阵的样子,[2,1]和[2,2]位置上的值就是0咯,或者随便怎么搞一下,毕竟用不到

代码

#include<bits/stdc++.h>
#define ll long long 
#define P 30013
using namespace std;
ll n,a,b;
struct matrix{
	ll a[4][4];
	matrix(int t=0){
		memset(a,0,sizeof(a));
		for(int i=1;i<=2;++i) a[i][i]=t;
	}
	friend inline matrix operator *(const matrix &a,const matrix &b){
		matrix c(0);
		for(int i=1;i<=2;++i)
			for(int j=1;j<=2;++j)
				for(int k=1;k<=2;++k)
					c.a[i][j]=(c.a[i][j]+(a.a[i][k]%P)*b.a[k][j])%P;
		return c;
	}
	friend inline matrix operator ^ (matrix a,ll b){//long long
		matrix res(1);
		while(b){
			if(b&1) res=res*a;
			a=a*a;
			b>>=1;
		}
		return res;
	}
}A,B;
int main(){
	cin>>a>>b>>n;
	if(n==1||n==2) {
		printf("1");
		return 0;
	} 
	//n-2
	A.a[1][1]=1;A.a[1][2]=1;A.a[2][1]=(a+b)%P;A.a[2][2]=1;
	B.a[1][1]=a;B.a[1][2]=1;B.a[2][1]=b;B.a[2][2]=0;
	B=B^(n-2);
	A=A*B;
	printf("%d",A.a[1][1]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42557561/article/details/82989177