【2016ICPC 沈阳onsite C】Recursive sequence(矩阵快速幂)

题面
给你一个递推式 F [ n ] = 2 F [ n 2 ] + F ( n 1 ) + n 4 F[n]=2*F[n-2]+F(n-1)+n^4
F ( n ) F(n) .
我原本以为矩阵快速幂只能用来求线性递推,还是太菜了。
对于这个题母,我们注意到有有一个 n 4 n^4 ,我们怎么办呢。
因为我们无法线性的从 n 4 n^4 ( n + 1 ) 4 (n+1)^4 ,但是我们可以分解。
我们发现 ( n + 1 ) 4 = n 4 + 4 n 3 + 6 n 2 + 4 n + 1 (n+1)^4=n^4+4*n^3+6*n^2+4^*n+1
以此类推,我们在一个矩阵中把 F ( n ) , F ( n + 1 ) , n 4 , n 3 , n 2 , n , 1 F(n),F(n+1),n^4,n^3,n^2,n,1 加入即可.
根据系数来分配矩阵元素。再套一下矩阵快速幂即可。

#include<bits/stdc++.h>
using namespace std;
typedef  long long ll;
const ll maxn = 1000;
const ll mod=2147493647;
struct mart{
    ll m[100][100];
}unit;
mart mult(mart a,mart b){
    mart ans;
    for(ll i=0;i<9;i++){
        for(ll j=0;j<9;j++){
            ll x=0;
            for(ll k=0;k<9;k++){
                x+=(a.m[i][k]*b.m[k][j]);
                x%=mod;
//                cout<<a.m[i][k]<<" "<<b.m[k][j]<<endl;
            }
            ans.m[i][j]=x%mod;;
        }
    }
    return ans;
}
void init(){
    memset(unit.m,0,sizeof(unit.m));
    for(ll i=0;i<9;i++){
        unit.m[i][i]=1;
    }
}
mart qpow(mart a,ll x){
    init();
    mart rt=unit;
    while(x){
        if(x&1) rt=mult(rt,a);
        a=mult(a,a);
        x>>=1;
    }
    return rt;
}

ll solve3(ll n,ll a1,ll b1){
    mart a;
    a.m[0][0]=0,a.m[0][1]=1,a.m[0][2]=0,a.m[0][3]=0,a.m[0][4]=0,a.m[0][5]=0,a.m[0][6]=0;
    a.m[1][0]=2,a.m[1][1]=1,a.m[1][2]=1,a.m[1][3]=0,a.m[1][4]=0,a.m[1][5]=0,a.m[1][6]=0;
    a.m[2][0]=0,a.m[2][1]=0,a.m[2][2]=1,a.m[2][3]=4,a.m[2][4]=6,a.m[2][5]=4,a.m[2][6]=1;
    a.m[3][0]=0,a.m[3][1]=0,a.m[3][2]=0,a.m[3][3]=1,a.m[3][4]=3,a.m[3][5]=3,a.m[3][6]=1;
    a.m[4][0]=0,a.m[4][1]=0,a.m[4][2]=0,a.m[4][3]=0,a.m[4][4]=1,a.m[4][5]=2,a.m[4][6]=1;
    a.m[5][0]=0,a.m[5][1]=0,a.m[5][2]=0,a.m[5][3]=0,a.m[5][4]=0,a.m[5][5]=1,a.m[5][6]=1;
    a.m[6][0]=0,a.m[6][1]=0,a.m[6][2]=0,a.m[6][3]=0,a.m[6][4]=0,a.m[6][5]=0,a.m[6][6]=1;
    mart b;
//    mart c=qpow(a,n-1);
    b.m[0][0]=a1%mod;
    b.m[1][0]=b1%mod;
    b.m[2][0]=81;
    b.m[3][0]=27;
    b.m[4][0]=9;
    b.m[5][0]=3;
    b.m[6][0]=1;
    mart ans=mult(qpow(a,n-1),b);
    return ans.m[0][0]%mod;
}

int main(){
    ll t;
    cin>>t;
    ll n,b,c;
    while(t--){
        cin>>n>>b>>c;
        cout<<solve3(n,b,c)<<endl;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/duanghaha/article/details/82945027