Matrix Fast Power - Xiangtan University

Link: https://www.nowcoder.com/acm/contest/105/G
Source: Niuke.com

Topic description

This is an enhanced version of the Fibonacci sequence.
Given recursion
Find the value of F(n). Since this value may be too large, take modulo 10 9 +7.

Enter description:

The first line is an integer T (1 ≤ T ≤ 1000), representing the number of samples. 
After each sample line, is an integer n (1 ≤ n ≤ 10
18
)。

Output description:

Each example outputs one line, an integer representing F(n) mod 1000000007.
Example 1

enter

4
1
2
3
100

output

1
16
57
558616258 

question meaning: A relatively naked question, as long as the matrix is ​​constructed, it is very easy.
Code example:
#define ll long long
const ll maxn = 1e6+5;
const ll mod = 1000000007;
const double eps = 1e-9;
const double pi = acos(-1.0);
const ll inf = 0x3f3f3f3f;

ll n;
struct mat
{
    ll a[10][10];
};
const ll modulu[10][10] = {
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0},
    {0, 0, 1, 3, 3, 1},
    {0, 0, 0, 1, 2, 1},
    {0, 0, 0, 0, 1, 1},
    {0, 0, 0, 0, 0, 1}
};

mat mul (mat a, mat b) {
    mat r;
    memset(r.a, 0, sizeof(r.a));
    
    for(ll i = 0; i < 6; i++){
        for(ll j = 0; j < 6; j++){
            for(ll k = 0; k < 6; k++){
                r.a[i][j] += (a.a[i][k]*b.a[k][j])%mod;
                r.a[i][j] %= mod;            
            }
        }
    }
    return r;
}

mat qpow(mat a, ll x){
    mat b;
    memset(b.a, 0, sizeof(b.a));
    for(ll i = 0; i <6; i++) b.a[i][i] = 1;
    
    while(x){
        if (x&1) b = mul(b, a);
        a = mul(a, a);
        x >>= 1;
    }
    return b;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    ll t;
    
    cin >> t;
    while(t--){
        scanf("%lld", &n);
        mat a;
        memcpy (aa, module, sizeof (module));
        if (n == 1) {printf("1\n"); continue;}
        else if (n == 0) {printf("0\n"); continue;}
        //for(ll i = 0; i < 6; i++){
            //for(ll j = 0; j < 6; j++){
                //prllf("%d ", a.a[i][j]);
            //}
            //prllf("\n");
        //}
        a = qpow(a, n-1);
        ll sum = a.a[0][0]+a.a[0][2]*8+a.a[0][3]*4+a.a[0][4]*2+a.a[0][5];
        printf("%lld\n", sum%mod);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325113938&siteId=291194637