用 T(n)=(F1+2F2+3F3+…+nFn)modm 表示 Fibonacci 数列前 n 项变形后的和 modm 的值。
现在佳佳告诉你了一个 n 和 m,请求出 T(n) 的值。
输入格式:
共一行,包含两个整数 n 和 m。
输出格式:
共一行,输出 T(n) 的值。
数据范围:
1≤n,m≤231−1
输入样例:
5 5
输出样例:
1
样例解释
T(5)=(1+2×1+3×2+4×3+5×5)mod5=1
题目:https://www.acwing.com/activity/content/11/
另一道稍微简单的题:https://blog.csdn.net/Are_you_ready/article/details/112369859
题解:因为要用矩阵快速幂,所以不能出现一个变量系数,所以要想办法去掉那个系数,经过一些变换就可以实现
由上面公式即可推出需要乘的矩阵
#include
#include
using namespace std;
typedef long long ll;
const int N=4;
ll n,m;
void mul(int f[],int a[][N]){
int temp[N]={0};
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
temp[i]=(temp[i]+(ll)f[j]*a[j][i])%m;
}
}
memcpy(f,temp,sizeof(temp));
}
void mul(int c[][N],int a[][N]){
int temp[N][N]={0};
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
temp[i][j]=(temp[i][j]+(ll)c[i][k]*a[k][j])%m;
}
}
}
memcpy(c,temp,sizeof(temp));
}
int main()
{
int f[N]={1,1,1,0};
int a[][N]={{0,1,0,0},{1,1,1,0},{0,0,1,1},{0,0,0,1}};
cin>>n>>m;
ll t=n;
n--;
while(n){
if(n&1)mul(f,a);
mul(a,a);
n=n>>1;
}
cout<<(((ll)t*f[2]-f[3])%m+m)%m<<endl;
return 0;
}