矩阵快速幂

例题(简单):

http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/1132.html

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stack>
#include<map>
#include<stack>
using namespace std;
# define maxn 100
# define ll long long
struct Matrix
{
    int a[maxn][maxn];
    Matrix operator *( Matrix b)
    {
        Matrix temp;
        for(int i=1; i<=2; i++)
        {
            for(int j=1; j<=2; j++)
            {
                temp.a[i][j]=0;
                for(int k=1; k<=2; k++)
                {
                    temp.a[i][j]+=a[i][k]*b.a[k][j];
                }
            }
        }
        return temp;
    }
} a;
Matrix quickpow(Matrix t,int w)
{
    Matrix temp=t;
    w--;
    while(w)
    {
        if(w&1)
        {
            temp=temp*t;
        }
        w>>=1;
        t=t*t;
    }
    return temp;
}

int main()
{
    int n;
    cin>>n;
    Matrix t;
    t.a[1][1]=1;
    t.a[1][2]=1;
    t.a[2][1]=1;
    t.a[2][2]=0;//初始矩阵
    if(n==1)
        cout<<1<<endl;
    else if(n==2)
        cout<<1<<endl;
    else
    {
        t=quickpow(t,n-2);
        int temp=t.a[1][1]+t.a[2][1];
        cout<<temp<<endl;
    }
    return 0;
}

例题(较难):

题目链接:https://vjudge.net/problem/HDU-5950

AC代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define mod 2147493647
struct Matrix
{
    ll t[10][10];
    Matrix operator *(Matrix a)
    {
        Matrix temp;
        for(int i=0; i<7; i++)
        {
            for(int j=0; j<7; j++)
            {
                temp.t[i][j]=0;
                for(int k=0; k<7; k++)
                {
                    temp.t[i][j]+=a.t[i][k]*t[k][j];
                    temp.t[i][j]%=mod;
                }
            }
        }
        return temp;
    }
};

Matrix quickpow(Matrix t1, ll t2)
{
    Matrix s;
    s=t1;
    t2--;
    while(t2)
    {
        if(t2&1)s=s*t1;
        t2>>=1;
        t1=t1*t1;
    }
    return s;
}
ll n,a,b;
int main()
{
    ll T;

    scanf("%lld",&T);
    while(T--)
    {
        Matrix w;
    w.t[0][0]=1;
    w.t[0][1]=1;
    w.t[0][2]=0;
    w.t[0][3]=0;
    w.t[0][4]=0;
    w.t[0][5]=0;
    w.t[0][6]=0;
    w.t[1][0]=2;
    w.t[1][1]=0;
    w.t[1][2]=0;
    w.t[1][3]=0;
    w.t[1][4]=0;
    w.t[1][5]=0;
    w.t[1][6]=0;
    w.t[2][0]=1;
    w.t[2][1]=0;
    w.t[2][2]=1;
    w.t[2][3]=0;
    w.t[2][4]=0;
    w.t[2][5]=0;
    w.t[2][6]=0;
    w.t[3][0]=4;
    w.t[3][1]=0;
    w.t[3][2]=4;
    w.t[3][3]=1;
    w.t[3][4]=0;
    w.t[3][5]=0;
    w.t[3][6]=0;
    w.t[4][0]=6;
    w.t[4][1]=0;
    w.t[4][2]=6;
    w.t[4][3]=3;
    w.t[4][4]=1;
    w.t[4][5]=0;
    w.t[4][6]=0;
    w.t[5][0]=4;
    w.t[5][1]=0;
    w.t[5][2]=4;
    w.t[5][3]=3;
    w.t[5][4]=2;
    w.t[5][5]=1;
    w.t[5][6]=0;
    w.t[6][0]=1;
    w.t[6][1]=0;
    w.t[6][2]=1;
    w.t[6][3]=1;
    w.t[6][4]=1;
    w.t[6][5]=1;
    w.t[6][6]=1;
        scanf("%lld%lld%lld",&n,&a,&b);
        if(n==1)printf("%lld
",a);
        else if(n==2)printf("%lld
",b);
        else if(n>2)
        {
            Matrix ans=quickpow(w,n-2);
            ll num=0;
            num+=b*ans.t[0][0];
            num%=mod;
            num+=a*ans.t[1][0];
            num%=mod;
            num+=16*ans.t[2][0];
            num%=mod;
            num+=8*ans.t[3][0];
            num%=mod;
            num+=4*ans.t[4][0];
            num%=mod;
            num+=2*ans.t[5][0];
            num%=mod;
            num+=ans.t[6][0];
            num%=mod;
            printf("%lld
",num);
        }
    }
    return 0;

}