题解:CF1439D INOI Final Contests

· · 题解

锣鼓题解一篇也没看懂,我太🥬了!不过有一说一,所有的题解都感觉是知道了最终结果然后反过来写的“代码解说”一类的东西,没有思路比较顺畅的😨。

给出参考代码。

#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;
}

tp mod;
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() {
   ios::sync_with_stdio(false), cin.tie(nullptr);
}

constexpr tp N = 505;
tp n, m;
array<tp, N> fac, ifc, f1, f2;
array<array<tp, N>, N> c, g1, g2;

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 >> mod;
   for (tp i = 0; i <= n; ++i) {
      c[i][0] = 1;
      for (tp j = 1; j <= i; ++j) c[i][j] = norm(c[i - 1][j - 1] + c[i - 1][j]);
   }

   f1[0] = 1;
   for (tp i = 1; i <= n; ++i) {
      for (tp j = 1; j <= i; ++j) {
         add(f1[i], 1ll * f1[j - 1] * f1[i - j] % mod * c[i - 1][j - 1] % mod);
         tp w = 1ll * f1[j - 1] * f2[i - j] % mod + 1ll * f2[j - 1] * f1[i - j] % mod;
         add(f2[i], 1ll * (i + 1) * norm(w) % mod * c[i - 1][j - 1] % mod);
         add(f2[i], 1ll * norm(c[j][2] + c[i - j + 1][2]) * f1[j - 1] % mod * f1[i - j] % mod * c[i - 1][j - 1] % mod);
      }
      f1[i] = 1ll * (i + 1) * f1[i] % mod;
   }

   g1[0][0] = 1;
   for (tp i = 1; i <= n; ++i) {
      for (tp j = 0; j < i; ++j) {
         g1[i][j] = g1[i - 1][j], g2[i][j] = g2[i - 1][j];
         for (tp l = 1; l <= j; ++l) {
            add(g1[i][j], 1ll * f1[l] * g1[i - l - 1][j - l] % mod * c[j][l] % mod);
            add(g2[i][j], 1ll * f1[l] * g2[i - l - 1][j - l] % mod * c[j][l] % mod);
            add(g2[i][j], 1ll * f2[l] * g1[i - l - 1][j - l] % mod * c[j][l] % mod);
         }
      }
      g1[i][i] = f1[i], g2[i][i] = f2[i];
   }
   cout << g2[n][m] << "\n";
   return 0;
}

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