首页 > 代码库 > hdu4686 简单的矩阵快速幂求前n项和

hdu4686 简单的矩阵快速幂求前n项和

HDU4686

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4686

题意:题目说的很清楚了,英语不好的猜也该猜懂了,就是求一个表达式的前n项和,矩阵快速幂一般多加一行一列来完成这个加的操作。具体看代码吧。比较简单,唯一有一点坑的地方,就是ax和bx可能比较大,在求ax*bx的时候,要考虑溢出的问题,需要先mod。其他没有了,直接看代码吧!

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
#define n 5 
#define mod 1000000007
using namespace std;
typedef long long ll;
ll a0,b0,ax,bx,ay,by;
struct Matrix{
    ll mat[15][15];
    Matrix operator * (const Matrix & m) const{
        Matrix tmp;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                tmp.mat[i][j]=0;
                for(int k=0;k<n;k++){
                    tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%mod;
                    tmp.mat[i][j]%=mod;
                }
            }
        return tmp;
    }
};
Matrix q_power(Matrix a,ll k){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=0;i<n;i++) ans.mat[i][i]=1;
    while(k){
        if(k&1) ans=ans*a;
        k/=2;
        a=a*a;
    }
    return ans;
    
}
int main() {
    ios::sync_with_stdio(false);cin.tie(0);
    ll T;
    while(cin>>T>>a0>>ax>>ay>>b0>>bx>>by){
        if(T==0){cout<<0<<endl;continue;}
        Matrix m;
        memset(m.mat,0,sizeof(m.mat));
        m.mat[0][0]=m.mat[0][4]=ax*bx%mod;
        m.mat[1][0]=ax*by%mod;m.mat[1][1]=ax%mod;m.mat[1][4]=ax*by%mod;
        m.mat[2][0]=bx*ay%mod;m.mat[2][2]=bx%mod; m.mat[2][4]=bx*ay%mod;
        m.mat[3][0]=by*ay%mod;m.mat[3][1]=ay%mod;m.mat[3][2]=by%mod;m.mat[3][3]=1;m.mat[3][4]=by*ay%mod;
        m.mat[4][4]=1;
        Matrix p=q_power(m,T-1);
        Matrix f;
        memset(f.mat,0,sizeof(f.mat));
        f.mat[0][0]=f.mat[0][4]=a0*b0%mod;f.mat[0][1]=a0%mod;f.mat[0][2]=b0%mod;f.mat[0][3]=1;
        f=f*p;
        cout<<f.mat[0][4]<<endl;
    }  
    return 0;
}

矩阵有点难画,我就不画了,根据我的对矩阵m的赋值,把矩阵画出来,你就会明白了为什么这个构造矩阵了

hdu4686 简单的矩阵快速幂求前n项和