// Gemini 3 Thinking /** * Problem Analysis: * We are merging columns in a binary tree structure. * Let's classify the "state" of a column by the color of its head person. * - If a column headed by Warm (W) meets a column headed by Cold (C), W wins the head position. * - If W meets W, winner is W. * - If C meets C, winner is C. * * Effectively, W is dominant. A column has a Cold head if and only if ALL head-to-head comparisons * leading to this state were won by Cold. Given the rules, this implies that for a specific binary * tree structure, the head is Cold iff all people in the specific positions that "compete" for the * head are Cold. * * Actually, simpler logic: * For the final permutation to be valid, for every canonical split into Left (L) and Right (R) halves: * It is FORBIDDEN to have Head(L) == Cold and Head(R) == Warm. * Because if Head(L) was Cold and Head(R) was Warm, they would merge as (R, L), not (L, R). * * Let W_t(x) be the generating function for the number of valid color patterns of length 2^t * where the head is Warm, indexed by the number of Cold people. * Let C_t(x) be the same for Head == Cold. * * Base case t=0: * W_0(x) = 1 (1 pattern "W", 0 Cold people) * C_0(x) = x (1 pattern "C", 1 Cold person) * * Transitions t -> t+1: * Merge L and R. * Valid merges for New Head Warm: * 1. Head(L)=W, Head(R)=W. (Valid, New Head W). Count: W_t * W_t * 2. Head(L)=W, Head(R)=C. (Valid, New Head W). Count: W_t * C_t * Total W_{t+1} = W_t * (W_t + C_t). * * Valid merges for New Head Cold: * 1. Head(L)=C, Head(R)=C. (Valid, New Head C). Count: C_t * C_t * (Note: Head(L)=C, Head(R)=W is invalid). * * Observation: * C_t(x) will always be x^{2^t}. Because if there is even one Warm person, * they will eventually bubble up to the head if they meet a Cold person. * Wait, "all people are Cold" is the only case for Cold Head? * Yes. If there is a Warm person, consider the "highest" node in the tournament tree * where a Warm-headed list meets a Cold-headed list. The Warm head wins. * Thus the root will be Warm-headed unless no such meeting occurs (all Cold). * * So C_t(x) = x^{2^t}. * Algorithm: * P = {1} * For t = 0 to N-1: * Sz = 2^t * P_next = P * (P + x^Sz) * P = P_next * Trim P to size M+1 if necessary. * * Final Answer: P[M] * M! * (2^N - M)! * Exception: If M = 2^N, P[M] is 0 (since P counts Warm heads), but valid config exists (All Cold). * However, if M = 2^N, the answer is simply (2^N)! since all are Cold. */ #include #include #include #include #include using namespace std; using namespace atcoder; using mint = modint998244353; // Factorial calculation helper mint factorial(int n) { mint res = 1; for (int i = 1; i <= n; ++i) res *= i; return res; } int main() { // Optimize I/O operations ios_base::sync_with_stdio(false); cin.tie(NULL); int N; int M; if (!(cin >> N >> M)) return 0; int num_people = 1 << N; // Edge Case: If everyone is Cold, the head is always Cold. // The standard DP tracks Warm-headed configurations. // Since everyone is the same color (Cold), any permutation is valid // because all merges are (Cold, Cold) -> Arbitrary order. if (M == num_people) { cout << factorial(num_people).val() << endl; return 0; } // P stores the coefficients for Warm-headed configurations. // P[k] = number of valid color patterns of current size with exactly k Cold people. // Initially size 1 (2^0), 0 Cold people. vector P = {1}; for (int t = 0; t < N; ++t) { int S = 1 << t; // Current size of blocks being merged (2^t) // We want to compute P_{next} = P * (P + x^S). // x^S represents the single valid pattern of size S where head is Cold (all Cold). // P covers cases where head is Warm (implies not all Cold, so max Cold is S-1? // Actually P can have terms up to x^S if we just talk about polynomials, // but structurally Warm head means at least one Warm, so Cold count < S is correct). // Construct Q = P + x^S vector Q = P; // We only need coefficients up to M. // The term x^S contributes to the result only if we are looking for indices >= S. // If M < S, then x^S * P will result in terms with x^{S + ...} which are > x^M. // So we only add x^S to Q if S <= M. if (S <= M) { // Ensure Q has enough space to hold the term x^S if ((int)Q.size() <= S) { Q.resize(S + 1, 0); } Q[S] += 1; } // Convolve P and Q P = convolution(P, Q); // Optimization: We only care about the coefficient for x^M. // Terms with power > M are irrelevant. if ((int)P.size() > M + 1) { P.resize(M + 1); } } // P[M] is the number of valid color patterns of length 2^N with M Cold people (Head Warm). // Since M != 2^N (handled above), the head MUST be Warm for any valid configuration with M Cold people. // (If head were Cold, everyone would have to be Cold). mint ans = 0; if (M < (int)P.size()) { ans = P[M]; } // Multiply by permutations of the specific people // M! ways to assign specific Cold people to the Cold positions // (2^N - M)! ways to assign specific Warm people to the Warm positions ans *= factorial(M); ans *= factorial(num_people - M); cout << ans.val() << endl; return 0; }