牛客挑战赛44 F
斐波那契?数列!
https://ac.nowcoder.com/acm/contest/8051/F
F
题意
第一部分:给定 ,其中
,求
。
第二部分:多组询问 ,求
,其中
是斐波那契数列。
题解
第一部分:矩阵快速幂,记录 这七个值的转移即可。转移矩阵可以通过简单计算得出。
第二部分:利用 即可。
#include <bits/stdc++.h> #define MOD 998244353 using namespace std; inline int modadd(int x, int y){ return (x + y >= MOD ? x + y - MOD: x + y); } char s[50]; int a1, a2, a3, x, y, z; __int128_t n; void init1(){ scanf("%s%d%d%d%d%d%d", s, &a1, &a2, &a3, &x, &y, &z); int l = strlen(s); n = 0; for (int i = 0; i < l; ++i) n = n * 10 + s[i] - '0'; } int I[7][7] = {0}, A[7][7] = {0}, B[7][7] = {0}, vec[7]; void mul(int F[][7], int G[][7], int H[][7]){ for (int i = 0; i < 7; ++i){ for (int j = 0; j < 7; ++j){ int res = 0; for (int k = 0; k < 7; ++k) res = modadd(res, 1ll * F[i][k] * G[k][j] % MOD); H[i][j] = res; } } } void solve1(){ if (n == 1) { int res = 1ll * a1 * a1 % MOD; printf("%d\n", res); return ; } if (n == 2){ int res = 1ll * a1 * a1 % MOD; res = modadd(res, 1ll * a2 * a2 % MOD); printf("%d\n", res); return ; } int t1 = modadd(1ll * z * z % MOD, 2ll * x * y % MOD * z % MOD); int t2 = modadd(2ll * y * z % MOD, 2ll * x * x % MOD * z % MOD); for (int i = 0; i < 7; ++i) I[i][i] = 1; A[0][0] = 1ll * x * x % MOD; A[0][1] = 1ll * y * y % MOD; A[0][2] = t1; A[0][3] = 2ll * x * y % MOD; A[0][4] = t2; A[0][5] = 2ll * x * z % MOD * z % MOD; A[3][0] = x; A[3][2] = 1ll * y * z % MOD; A[3][3] = y; A[3][4] = 1ll * x * z % MOD; A[3][5] = 1ll * z * z % MOD; A[1][0] = A[2][1] = A[4][3] = A[5][4] = A[6][0] = A[6][6] = 1; n -= 3; while (n > 0){ if (n % 2 != 0){ mul(I, A, B); for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) I[i][j] = B[i][j]; } mul(A, A, B), n /= 2; for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) A[i][j] = B[i][j]; } int a4 = modadd(1ll * x * a3 % MOD, modadd(1ll * y * a2 % MOD, 1ll * z * a1 % MOD)); vec[0] = 1ll * a4 * a4 % MOD; vec[1] = 1ll * a3 * a3 % MOD; vec[2] = 1ll * a2 * a2 % MOD; vec[3] = 1ll * a4 * a3 % MOD; vec[4] = 1ll * a3 * a2 % MOD; vec[5] = 1ll * a2 * a1 % MOD; vec[6] = modadd(1ll * a1 * a1 % MOD, modadd(1ll * a2 * a2 % MOD, 1ll * a3 * a3 % MOD)); int ans = 0; for (int i = 0; i < 7; ++i) ans = modadd(ans, 1ll * I[6][i] * vec[i] % MOD); printf("%d\n", ans); } pair<int, int> fib(int n) { if (n == 0) return {0, 1}; auto p = fib(n >> 1); int c = 1ll * p.first * modadd(2ll * p.second % MOD, MOD - p.first) % MOD; int d = modadd(1ll * p.first * p.first % MOD, 1ll * p.second * p.second % MOD); if (n & 1) return {d, modadd(c, d)}; else return {c, d}; } void solve2(){ int q, x; scanf("%d", &q); while (q--){ scanf("%d", &x); auto p = fib(x); int ans = 1ll * p.first * p.second % MOD; printf("%d\n", ans); } } int main(){ init1(); solve1(); solve2(); return 0; }