Recursive sequence HDU --- 5950 【公式矩阵快速幂】

来源:互联网 发布:腾讯云域名和ip绑定 编辑:程序博客网 时间:2024/05/29 15:09

传送门

思路:因为直接给了公式, 所以可以直接推的我们所需要的目标矩阵, 如果没有什么思路的话看看另外一篇原理介绍, 里面有一遍博客讲的炒鸡好!

(怎么推要求那个矩阵的几次方,就是用等比数列,an = a(n-1) * q ,然后看题目给的那一项从而推出是q的几次方.)

AC代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>#define ll long longusing namespace std;const ll mod = 2147493647;struct Ma{    ll a[10][10];    void cc()    {        memset(a,0,sizeof(a));    }    Ma operator * (const Ma & b) const {        Ma tmp;        tmp.cc();        for(int i=0;i<7;i++){            for(int j=0;j<7;j++){                for(int k=0;k<7;k++){                    tmp.a[i][j] += (a[i][k] * b.a[k][j]);                    tmp.a[i][j] %= mod;                }            }        }        return tmp;    }}res,x;void init(){    res.cc();    for(int i=0;i<7;i++)    //初始化为单位矩阵.        res.a[i][i] = 1 ;    x.cc();    // 初始化所推的那个矩阵.    x.a[0][0] = x.a[0][1] = 1;    x.a[1][0] = 2;    x.a[2][0] = x.a[2][2] = 1;    x.a[3][2] = 4 , x.a[3][3]=1;    x.a[4][2] = 6 , x.a[4][3] = 3 ,x.a[4][4] = 1 ;    x.a[5][2] = 4 , x.a[5][3] = 3 , x.a[5][4] = 2 , x.a[5][5] = 1 ;    x.a[6][2] = x.a[6][3] = x.a[6][4] = x.a[6][5] = x.a[6][6] = 1;}void qpow(ll n){    while(n)    {        if(n&1) res = res * x;        x = x*x ;        n >>= 1;    }}int main(){    int t;    cin >> t;    while(t--){        ll N,m,n;        init();        cin >> N >> m >> n;        if(N < 3){            if(N == 1)                cout << m << endl;            else                cout << n << endl;            continue;        }        ll s[10] = {n,m,81,27,9,3,1};   //相当于第2项那个.这个就要自己想了.        qpow(N-2);        ll ans = 0 ;        for(int i=0;i<7;i++){            ans += ( res.a[i][0] * s[i] );            ans %= mod;        }        cout << ans << endl;    }}
阅读全文
0 0