版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 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
- 两个矩阵可以相乘的前提条件是,A矩阵的列数=B矩阵的行数
- 矩阵乘法不满足交换律,但满足结合律
分析
这个数据规模写得很鬼畜啊……搞得我都忘了开long long,wa了两次。我还以为那个150%是过来凑热闹的,结果就gg了
话说150%的数据是什么意思啊?求大佬帮看
说回这道题,就是稍微推一下矩阵的方程,然后快速幂乱搞一下
推的时候傻逼了一下,两个矩阵相乘只要A矩阵的列数=B矩阵的行数就行了
最后推出来的方程就是
然后为了方便矩阵快速幂,我们把第一个弄成方阵的样子,[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;
}