数论基础--矩阵快速幂 及其例题

比较详细的讲解了如何构造这个矩阵
https://blog.csdn.net/Akatsuki__Itachi/article/details/80443939
这是几个常用的递推式。
i 3 i^3 i3是如何推出来的,他就需要结合二项式定理通过 i 2 i^2 i2 i 1 i^1 i1推得。
数论基础--矩阵快速幂 及其例题_第1张图片
例题:来源:河南理工大学2020暑期集训第二次积分赛 C题
例题f[i] = f[ii 1]+f[ii 2]+i3。
解题思路如下(来源:官方题解):
数论基础--矩阵快速幂 及其例题_第2张图片代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include 
#include 
#include 
#include 
#include 
const int maxn = 101000;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1e9+7;
using namespace std;

struct node{
    ll m[10][10];
};

node mul(node a,node b){
    node ans;
    memset(ans.m,0,sizeof ans.m);
    for(int i=0;i<6;i++)
        for(int j=0;j<6;j++)
            for(int k=0;k<6;k++)
                ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
    return ans;
}

node pow(node a,ll b){
    node ans;
    memset(ans.m,0,sizeof ans.m);
    for(int i=0;i<6;i++) ans.m[i][i]=1;
    while(b){
        if(b&1) ans=mul(ans,a);
        a=mul(a,a);
        b>>=1;
    }
    return ans;
}

node x={{
	{1,1,1,0,0,0},
	{1,0,0,0,0,0},
	{0,0,1,3,3,1},
	{0,0,0,1,2,1},
	{0,0,0,0,1,1},
	{0,0,0,0,0,1}
}};
node y={{
    {5,0,0,0,0,0},
    {2,0,0,0,0,0},
    {27,0,0,0,0,0},
    {9,0,0,0,0,0},
    {3,0,0,0,0,0},
    {1,0,0,0,0,0},
    }};
int main(){
    int t;
    cin>>t;
    while(t--){
        ll n;
        node ans=x;
        cin>>n;
        if(n==1){
            cout<<2<<endl;
            continue;
        }
        if(n==2){
            cout<<5<<endl;
            continue;
        }
        ans=pow(ans,n-2);
        ans=mul(ans,y);
        cout<<ans.m[0][0]%mod<<endl;
    }
    return 0;
}

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