佳佳的斐波那契--acwing(矩阵乘法快速幂)

用 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
题解:因为要用矩阵快速幂,所以不能出现一个变量系数,所以要想办法去掉那个系数,经过一些变换就可以实现
佳佳的斐波那契--acwing(矩阵乘法快速幂)_第1张图片
由上面公式即可推出需要乘的矩阵
佳佳的斐波那契--acwing(矩阵乘法快速幂)_第2张图片

#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;
}

你可能感兴趣的:(数论)