1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#include <iostream>
#include <vector>
using matrix = std::vector< std::vector<long long> >;
constexpr long long mod = 1000000000; // 1,000,000,000
int fib( int N, const std::vector<long long>& b1, std::vector<long long> c1, int k );
matrix mul( const matrix& lhs, const matrix& rhs, int k );
// Beware! pow() is already defined in the standard library:
matrix pow( const matrix& base, int e, int k );
int main()
{
int cas;
std::cin >> cas;
for ( int i { 1 }, k; i <= cas; ++i) {
std::cin >> k;
std::vector<long long> b1 ( k + 1 );
std::vector<long long> c2 ( k + 1 );
for ( int j { 1 }, b; j <= k; ++j ) {
std::cin >> b;
b1[j] = b;
}
for( int o { 1 }, c; o <= k; ++o ) {
std::cin >> c;
c2[o] = c;
}
int n;
std::cin >> n;
fib( n, b1, c2, k );
}
}
matrix mul( const matrix& lhs, const matrix& rhs, int k )
{
matrix result( k + 1, std::vector<long long>(k + 1) );
for ( int i { 1 }; i <= k; ++i ) {
for ( int j { 1 }; j <= k; ++j ) {
for ( int m { 1 }; m <= k; ++m ) {
result[i][j] = ( result[i][j] + ( lhs[i][m] * rhs[m][j] ) ) % mod;
}
}
}
return result;
}
matrix pow( const matrix& base, int e, int k )
{
if ( e == 1 ) {
return base;
}
if ( e % 2 ) {
return mul( base,
pow( base, e - 1, k ),
k );
}
matrix result = pow( base, e/2, k );
return mul( result, result, k );
}
int fib( int N, const std::vector<long long>& b1, std::vector<long long> c1, int k )
{
std::vector<long long> result ( k + 1 );
for (int i { 1 }; i <= k; ++i) {
result[i] = b1[i];
}
matrix tmp( k + 1, std::vector<long long>( k + 1 ) );
for ( int y { 1 }; y <= k; ++y ) {
for ( int u { 1 }; u <= k; ++u ) {
if ( y + 1 == u ) {
tmp[y][u] = 1;
}
}
}
for ( int i { 1 }; i <= k; ++i ) {
long long y { c1.back() };
c1.pop_back();
tmp[k][i] = y;
}
if ( N < k ) {
std::cout << b1[N] << '\n';
return 0;
}
tmp = pow ( tmp, N - 1, k );
long long res {};
for ( int i { 1 }; i <=k ; ++i ) {
res = ( res + tmp[1][i] * result[i] ) % mod;
}
std::cout << res << '\n';
}
|