Hdu1588Gauss Fibonacci矩阵

题意:求 g(i)=k*i+b;  f(g(i)) for 0<=i<n。

 设 矩阵 A   ,  S = A^0 + A^1 + A^2 + ... + A^n 。

将这个序列分成两半 ,A^0 + A^1 + A^2 + ... + A^(n/2)      +       A^(n/2 + 1) *(A^0 + ... + A^(n/2))  + A^n  or A^0 + A^1 + A^2 + ... + A^(n/2)      +       A^(n/2 + 1) *(A^0 + ... + A^(n/2))  

#include <cstdio>

#include <algorithm>

#include <iostream>

#include <string.h>

typedef long long LL;

LL M;

using namespace std;

struct Matrix

{

    LL m[4][4];

};



Matrix Mul(Matrix a, Matrix b)

{

    Matrix ans;

    for (LL i = 0; i < 2; i++)

    for (LL j = 0; j < 2; j++){

        ans.m[i][j] = 0;

        for (LL k = 0; k < 2; k++)

            ans.m[i][j] += a.m[i][k] * b.m[k][j];

        ans.m[i][j] %= M;

    }

    return ans;

}



Matrix add(Matrix a, Matrix b)

{

    for (LL i = 0; i < 2; i++)

    for (LL j = 0; j < 2; j++)

        a.m[i][j] += b.m[i][j], a.m[i][j] %= M;

    return a;

}



Matrix quick(Matrix a, LL b)

{

    Matrix ans;

    for (LL i = 0; i < 2; i++)

    for (LL j = 0; j < 2; j++)

        ans.m[i][j] = (i == j);

    while (b){

        if (b & 1) ans = Mul(ans, a);

        a = Mul(a, a);

        b >>= 1;

    }

    return ans;

}



Matrix solve(Matrix a, LL len)

{

    if (len == 1){

        Matrix ans;

        for (int i = 0; i<2; i++)

        for (int j = 0; j<2; j++)

            ans.m[i][j] = (i == j);

        return ans;

    }

    Matrix ans = solve(a, len >> 1);

    Matrix t = quick(a, (len >> 1));

    t = Mul(t, ans);

    ans = add(ans, t);

    if (len & 1) return add(ans, quick(a, len - 1));

    return ans;

}



void gao(LL n, LL k, LL b)

{

    Matrix ans;

    ans.m[0][0] = 1; ans.m[0][1] = 1;

    ans.m[1][0] = 1; ans.m[1][1] = 0;

    Matrix  t = quick(ans, k);

    Matrix gg = solve(t, n);

    gg = Mul(gg, quick(ans, b));

    cout << gg.m[0][1] % M << endl;

}



int main()

{

    LL n, k, b;

    while (cin >> k >> b >> n >> M){

        gao(n, k, b);

    }

    return 0;

}

 

你可能感兴趣的:(fibonacci)