#include #include #include #include using namespace std; long long MOD = 998244353; const int D = 6; // Dimension of recurrence // Matrix multiplication for DxD matrices vector> multiply(const vector>& A, const vector>& B) { vector> C(D + 1, vector(D + 1, 0)); for (int i = 0; i <= D; ++i) { for (int j = 0; j <= D; ++j) { for (int k = 0; k <= D; ++k) { C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD; } } } return C; } // Matrix power using binary exponentiation vector> matrix_pow(vector> A, long long p) { vector> res(D + 1, vector(D + 1, 0)); for (int i = 0; i <= D; ++i) res[i][i] = 1; A[D][D] = 1; // Ensure the (D,D) element for affine transform is 1 initially while (p > 0) { if (p & 1) res = multiply(res, A); A = multiply(A, A); p >>= 1; } return res; } // Apply matrix to vector V = M * U vector apply_matrix_to_vector(const vector>& M, const vector& U) { vector V(D + 1, 0); for (int i = 0; i <= D; ++i) { for (int j = 0; j <= D; ++j) { V[i] = (V[i] + M[i][j] * U[j]) % MOD; } } return V; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N_val, M_val, k_queries; cin >> N_val >> M_val >> k_queries; // M_val is always 2 int limit_sum = 2 * N_val; vector f(limit_sum + D, 0); f[0] = 1; for (int i = 1; i < limit_sum + D; ++i) { for (int d = 1; d <= D; ++d) { if (i - d >= 0) { f[i] = (f[i] + f[i - d]) % MOD; } } } vector> T_std(D + 1, vector(D + 1, 0)); for (int j = 0; j < D; ++j) { T_std[0][j] = 1; } for (int i = 1; i < D; ++i) { T_std[i][i - 1] = 1; } T_std[D][D] = 1; vector> T_reset_proto(D + 1, vector(D + 1, 0)); // First row of M_zr is all zeros, so T_reset_proto[0][j] for j C_values(k_queries); for (int i = 0; i < k_queries; ++i) { cin >> C_values[i]; } for (int qi = 0; qi < k_queries; ++qi) { int C = C_values[qi]; vector U(D + 1, 0); // Represents (g[x-1]...g[x-6], 1)^T U[D] = 1; // for affine transformation // Initial state corresponds to g[-1]...g[-6] all 0. long long current_x = -1; vector critical_points; critical_points.push_back(C); if (C + N_val < limit_sum) { critical_points.push_back(C + N_val); } for (long long p : critical_points) { long long segment_len = p - 1 - current_x; if (segment_len > 0) { vector> T_std_pow_L = matrix_pow(T_std, segment_len); U = apply_matrix_to_vector(T_std_pow_L, U); } current_x = p - 1; // Reset at point p vector> T_reset_concrete = T_reset_proto; T_reset_concrete[0][D] = f[p]; // B_x vector's first component is f[p] U = apply_matrix_to_vector(T_reset_concrete, U); current_x = p; } long long final_segment_len = (limit_sum - 1) - current_x; if (final_segment_len > 0) { vector> T_std_pow_L = matrix_pow(T_std, final_segment_len); U = apply_matrix_to_vector(T_std_pow_L, U); } // Now U contains (g[2N-1], g[2N-2], ..., g[2N-6], 1)^T vector g_values(D); for(int i=0; i= limit_sum // d >= limit_sum - s // Smallest d is max(1, limit_sum - s) // Largest d is 6 // If max(1, limit_sum - s) > 6, count is 0 // Else count = 6 - max(1, limit_sum - s) + 1 long long min_d_to_terminate = limit_sum - s; if (min_d_to_terminate <= D) { // D is 6 term_rolls_count = D - max(1LL, min_d_to_terminate) + 1; } ans_C = (ans_C + g_values[s_idx] * term_rolls_count) % MOD; } cout << ans_C << "\n"; } return 0; }