矩阵加速

G. 跑步困难症

题解:g( i + 1) = g(i) + g( i - 1) + i ^ 2,g(i) = g(i - 1) + g( i - 2) + ( i - 1 ) ^ 2;

#include<bits/stdc++.h>
#define ll long long
#define P pair<int,int>
#define pb push_back
#define lson root << 1
#define INF (int)2e9 + 7
#define maxn (int)1e6 + 7
#define rson root << 1 | 1
#define LINF (unsigned long long int)1e18
#define mem(arry, in) memset(arry, in, sizeof(arry))
using namespace std;

const ll mod = 1000000007;

struct node{
    ll A[5][5];
    node() {
        mem(A, 0);
    }
    node operator * (const node tp) {
        node ans;
        for(int i = 0; i < 5; i++){
            for(int j = 0; j < 5; j++){
                for(int k = 0; k < 5; k++){
                    ans.A[i][j] += A[i][k] * tp.A[k][j];
                    ans.A[i][j] %= mod;
                }
            }
        }
        return ans;
    }
    void operator = (const node tp) {
        for(int i = 0; i < 5; i++){
            for(int j = 0; j < 5; j++){
                    A[i][j] = tp.A[i][j];
            }
        }
    }
};
node Fastpow(node C, ll x){
    node B;
    for(int i = 0; i < 5; i++) B.A[i][i] = 1;
    while(x){
        if(x & 1) B = B * C;
        C = C * C;
        x >>= 1;
    }
    return B;
}

int temp[5][5] = { {1, 1, 1, 0, 0}, {1, 0, 0, 0, 0}, {0, 0, 1, 2, -1}, {0, 0, 0, 1, 1}, {0, 0, 0, 0, 1} };

int main()
{
    int T;
    cin >> T;
    while(T--){
        int x;
        cin >> x;
        if(x == 1) cout << 1 << endl;
        else if(x == 2) cout << 2 << endl;
        else{
            node y;
            for(int i = 0; i < 5; i++){
                for(int j = 0; j < 5; j++) y.A[i][j] = temp[i][j];
            }
            y = Fastpow(y, x - 2);
            printf("%lld\n", (2 * y.A[0][0] + y.A[0][1] + 4 * y.A[0][2] + 3 * y.A[0][3] + y.A[0][4]) % mod);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/zgglj-com/p/9196674.html