题解:P11817 [PA 2019 Final] 数图 / Grafy
直接对邻接表计数,即计数满足
算子法告诉我们贡献可以改写成如下形式(记
枚举贡献形式,设分别有
考虑计数此时能产生贡献的排列
(这里标为红、蓝、绿、紫的部分分别是
将
这就给出了一个
#include <iostream>
using namespace std;
const int kN = 501;
int n, kM, fc[kN * 2], ic[kN], p2[kN * 2];
int inv(int a, int m = kM) { return a == 1 ? 1 : m - 1ll * inv(m % a, a) * m / a; }
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> kM;
for (int i = fc[0] = 1; i <= n * 2; ++i) {
fc[i] = 1ll * fc[i - 1] * i % kM;
}
ic[n] = inv(fc[n]);
for (int i = n; i >= 1; --i) {
ic[i - 1] = 1ll * ic[i] * i % kM;
}
for (int i = p2[0] = 1; i <= n * 2; ++i) {
p2[i] = p2[i - 1] * 2 % kM;
}
int ans = 0;
for (int i = 0; i <= n; ++i) {
for (int j = 0; i + j <= n; ++j) {
for (int k = 0; i + j + k <= n; ++k) {
int t = n - i - j - k;
ans = (ans + 1ll * ((i + j & 1) ? kM - 1 : 1) * fc[n] % kM * ic[i] % kM * ic[j] % kM * ic[k] % kM * ic[t] % kM * fc[n + t - j - k] % kM * p2[2 * (i + k) + j] % kM * fc[j + t] % kM * ic[t]) % kM;
}
}
}
cout << 1ll * ans * inv(p2[n * 2]) % kM;
return 0;
}