POJ-3070Fibonacci(矩阵快速幂求Fibonacci数列) uva 10689 Yet another Number Sequence【矩阵快速幂】

时间:2023-03-08 19:45:51

典型的两道矩阵快速幂求斐波那契数列

POJ 那是 默认a=0,b=1

UVA 一般情况是 斐波那契f(n)=(n-1)次幂情况下的(ans.m[0][0] * b + ans.m[0][1] * a);

 //POJ
#include <cstdio>
#include <iostream> using namespace std; const int MOD = ; struct matrix
{
int m[][];
}ans, base; matrix multi(matrix a, matrix b)
{
matrix tmp;
for(int i = ; i < ; ++i)
{
for(int j = ; j < ; ++j)
{
tmp.m[i][j] = ;
for(int k = ; k < ; ++k)
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
}
}
return tmp;
}
int fast_mod(int n) // 求矩阵 base 的 n 次幂
{
base.m[][] = base.m[][] = base.m[][] = ;
base.m[][] = ;
ans.m[][] = ans.m[][] = ; // ans 初始化为单位矩阵
ans.m[][] = ans.m[][] = ;
while(n)
{
if(n & ) //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t
{
ans = multi(ans, base);
}
base = multi(base, base);
n >>= ;
}
return ans.m[][];
} int main()
{
int n;
while(scanf("%d", &n) && n != -)
{
printf("%d\n", fast_mod(n));
}
return ;
}
 //uva
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=1e5+;
const double eps=1e-;
const double pi=acos(-);
#define ll long long
const int MOD = ; int a,b,n,m;
struct matrix
{
int m[][];
} ans, base; matrix multi(matrix a, matrix b)
{
matrix tmp;
for(int i = ; i < ; ++i)
{
for(int j = ; j < ; ++j)
{
tmp.m[i][j] = ;
for(int k = ; k < ; ++k)
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
}
}
return tmp;
}
int fast_mod(int n) // 求矩阵 base 的 n 次幂
{
base.m[][] = base.m[][] = base.m[][] = ;
base.m[][] = ;
ans.m[][] = ans.m[][] = ; // ans 初始化为单位矩阵
ans.m[][] = ans.m[][] = ;
while(n)
{
if(n & ) //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t
{
ans = multi(ans, base);
}
base = multi(base, base);
n >>= ;
}
// return ans.m[0][1];
} int main()
{
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d%d%d%d",&a,&b,&n,&m);
m = pow(, m);
if (n == )
{
printf("%d\n", (a%m + m) % m);
continue;
}
if (n == )
{
printf("%d\n", (b%m + m) % m);
continue;
}
fast_mod(n-);
int tmp = ((ans.m[][] * b + ans.m[][] * a) % m + m) % m;
printf("%d\n", tmp);
}
return ;
}