1. 程式人生 > >【2016ICPC 瀋陽onsite C】Recursive sequence(矩陣快速冪)

【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;
}