矩阵加速

 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

 H. 课上例题和课后习题

题解:a(n) = 2a(n - 1) + 3a(n - 2) + n * 4^n + 5n^2 - 6,a(n + 1) = 2a(n) + 3a(n - 1) + (n + 1) * 4^(n + 1) + 5(n + 1)^2 - 6;

#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 = 998244353;

struct node{
    ll A[7][7];
    node() { mem(A, 0); }
    node operator * (const node tp) {
        node ans;
        for(int i = 0; i < 7; i++){
            for(int j = 0; j < 7; j++){
                for(int k = 0; k < 7; 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 < 7; i++){
            for(int j = 0; j < 7; j++) A[i][j] = tp.A[i][j];
        }
    }
};

node Fastpow(node C, ll x){
    node B;
    for(int i = 0; i < 7; i++) B.A[i][i] = 1;
    while(x){
        if(x & 1) B = B * C;
        C = C * C;
        x >>= 1;
    }
    return B;
}

int temp[7][7] = { {2, 3, 1, 0, 5, 0, mod-6}, {1, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 4, 0, 0, 0}, {0, 0, 0, 4, 0, 0, 0}, {0, 0, 0, 0, 1, 2, 1}, {0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 1} };

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

经验:写成n+1的形式,然后展开,不同形式的就添加到列向量里面!!!!!

 

posted @ 2018-06-18 23:03  天之道,利而不害  阅读(490)  评论(0编辑  收藏  举报