nyoj--301 递推求值(矩阵快速幂)

来源:互联网 发布:多目标跟踪 知乎 编辑:程序博客网 时间:2024/04/29 18:27

nyoj 301

题解

用矩阵加速运算。
f(n)f(n1)1=b10a00c01f(n1)f(n2)1=b10a00c01n2f(2)f(1)1

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;struct mat{    int M[3][3];    mat(){        memset(M, 0, sizeof(M));    }};const int mod = 1000007;int t, a, b, c, f1, f2, n;mat mul(mat& A, mat& B){    mat C;    for(int i = 0; i < 3; ++i)        for(int j = 0; j < 3; ++j)            for(int k = 0; k < 3; ++k)                C.M[i][j] = (C.M[i][j] + (ll)A.M[i][k] * B.M[k][j] + mod) % mod;    return C;}mat pow(mat A, int n){    mat E;    for(int i = 0; i < 3; ++i) E.M[i][i] = 1;    while(n){        if(n & 1) E = mul(E, A);        A = mul(A, A);        n >>= 1;    }    return E;}int main(){    //freopen("data.in", "r", stdin);    //freopen("out2.out", "w", stdout);    mat A, B;    for(cin >> t; t--; )    {        scanf("%d %d %d %d %d %d", &f1, &f2, &a, &b, &c, &n);        if(n == 1 || n == 2){            cout << (n == 1 ? f1 : f2) << endl;            continue;        }        A.M[0][0] = b, A.M[0][1] = a, A.M[0][2] = c;        A.M[1][0] = 1, A.M[1][1] = 0, A.M[1][2] = 0;        A.M[2][0] = 0, A.M[2][1] = 0, A.M[2][2] = 1;        B.M[0][0] = f2, B.M[1][0] = f1, B.M[2][0] = 1;        A = pow(A, n - 2);        B = mul(A, B);        printf("%d\n", (B.M[0][0] + mod ) % mod);    }    return 0;}

下面这个用vector 作为二维数组,一直TLE..
还是第一次遇见,原因何在..
心里一万只草泥马奔腾而过…

#include <iostream>#include <vector>#include <cmath>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;typedef vector<ll> vec;typedef vector<vec> mat;const int mod = 1000007;int t, a, b, c, f1, f2, n;mat mul(mat& A, mat &B){    mat C(A.size(), vec(B[0].size()));    for(int i = 0; i < (int)A.size(); ++i)        for(int j = 0; j < (int)B[0].size(); ++j)            for(int k = 0; k < (int)B.size(); ++k)                C[i][j] = (C[i][j] + (ll)A[i][k] * B[k][j] + mod) % mod;    return C;}mat pow(mat A, int n){    mat B(A.size(), vec(A.size()));    for(int i = 0; i < (int)A.size(); ++i) B[i][i] = 1;    while(n){        if(n & 1) B = mul(B, A);        A = mul(A, A);        n >>= 1;    }    return B;}int main(){    //freopen("data.in", "r", stdin);    //freopen("out2.out", "w", stdout);    mat A(3, vec(3));    mat B(3, vec(1));    for(cin >> t; t--; )    {        scanf("%d %d %d %d %d %d", &f1, &f2, &a, &b, &c, &n);        if(n == 1 || n == 2){            cout << (n == 1 ? f1 : f2) << endl;            continue;        }        A[0][0] = b, A[0][1] = a, A[0][2] = c;        A[1][0] = 1, A[1][1] = 0, A[1][2] = 0;        A[2][0] = 0, A[2][1] = 0, A[2][2] = 1;        B[0][0] = f2, B[1][0] = f1, B[2][0] = 1;        A = pow(A, n - 2);        B = mul(A, B);        printf("%I64d\n", (B[0][0] + mod ) % mod);    }    return 0;}
0 0
原创粉丝点击