题解:CF1784D Wooden Spoon

· · 题解

#include <bits/stdc++.h>
using namespace std;
using tp = int;
constexpr tp INF = 1e9;
#define FULL(a) begin(a), end(a)
#define ALL(a, l, r) begin(a) + l, begin(a) + r + 1

template <typename T>
bool ckmax(T &x, T y) {
   if (y > x) return x = y, 1;
   return 0;
}
template <typename T>
bool ckmin(T &x, T y) {
   if (y < x) return x = y, 1;
   return 0;
}

constexpr tp mod = 998244353;
tp norm(tp x) { return x + (x < 0) * mod - (x >= mod) * mod; }
void add(tp &x, tp y) { x = norm(x + y); }
tp pow(tp x, tp y) {
   tp z = 1;
   for (; y; x = 1ll * x * x % mod, y >>= 1)
      if (y & 1) z = 1ll * z * x % mod;
   return z;
}

void QWQ() {
   //freopen(".in", "r", stdin), freopen(".out", "w", stdout);
   ios::sync_with_stdio(false), cin.tie(nullptr);
}

constexpr tp N = 21, M = (1 << 20) + 2;
tp n, m;
array<tp, M> f, g, fac, ifc;

tp bnm(tp n, tp m) {
   if (n < 0 || m < 0 || n < m) return 0;
   return 1ll * fac[n] * ifc[m] % mod * ifc[n - m] % mod;
}

tp HARUTO() {
   cin >> n, m = 1 << n;
   fac[0] = 1;
   for (tp i = 1; i <= m; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
   ifc[m] = pow(fac[m], mod - 2);
   for (tp i = m - 1; ~i; --i) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % mod;

   f[0] = 1;
   for (tp i = n; ~i; --i) {
      tp c = 1 << i - 1;
      g[0] = f[0], f[0] = 0;
      for (tp j = 1; j <= m; ++j) g[j] = norm(f[j] + g[j - 1]), f[j] = 0;
      if (i < 1) break;
      for (tp j = 1; j <= m; ++j) f[j] = 2ll * g[j - 1] * fac[c] % mod * bnm(m - j - c, c - 1) % mod;
   }
   for (tp i = 1; i <= m; ++i) cout << g[i - 1] << "\n";
   return 0;
}

int main() {
   QWQ();
   tp t = 1;
   while (t--) HARUTO();
   return 0;
}