当前位置: 首页 > news >正文

无标号有度数限制基环树森林计数

无标号有度数限制基环树森林计数

写这个的原因是前几天模拟赛考了这个,这个计数还是很有意思的,过程比较有启发性。

思路和代码均借鉴该博客,本文更多的是思路方向和细节上的一些补充。

我们要求的东西是给定 \(n,k\),求 \(n\) 个点,每个点入度不超过 \(k\) 的无标号内向基环树森林个数。

大体的思路是先求出 \(dp_n\) 表示 \(n\) 个点,度数限制下无标号有根树的方案数,再挂到环上算出 \(n\) 个点的基环树的方案数,最后合并成森林的方案数。

求无标号有根树方案数

先不考虑度数限制,那问题的关键是去重。暴力容斥什么的还是太吃操作了,考虑直接上生成函数来刻画这个情况。直接枚举子树大小,对于每种子树大小为了防止重复,在一起统计方案数。那么对于大小为 \(i\) 的子树枚举选它的个数,实际上方案数就是 \(x^0+x^i+x^{2i}+\cdots=\frac1{1-x^i}\),因此我们有:

\[dp_n=[x^{n-1}]\prod_{i=1}^\infty(\frac1{1-x^i})^{dp_i} \]

考虑加上度数限制。这个东西直接加一维硬算。那么有:

\[dp_n=\sum_{k\le K}[x^{n-1}y^k]\prod_{i=1}^\infty(\frac1{1-x^iy})^{dp_i} \]

加和的形式还是太吃操作了,考虑给这个东西乘上 \(\frac1{1-y}\) 实际上就能把所有 \(\le K\)\(k\) 系数为 \(1\) 地贡献到 \(K\),因此有:

\[dp_n=[x^{n-1}y^k]\prod_{i=1}^\infty(\frac1{1-x^iy})^{dp_i}\frac1{1-y} \]

现在的问题是转移的系数不好算。考虑如何算 \([x^t](\frac1{1-x^iy})^{dp_i}\) 。记 \(w=x^iy\),展开之后就是 \((w^0+w^1+\cdots)^{dp_i}\) 状物,那么求第 \(t\) 项系数就是等价于求 \(dp_i\) 个非负整数的和等于 \(t\),这个东西是 \(\binom{t+dp_i-1}{t}\)

\(dp_i\) 这个东西很大,取模带进去算对吗?啊是对的,考虑卢卡斯定理有 \(\binom{n}{m}=\binom{\lfloor\frac np\rfloor}{\lfloor\frac mp\rfloor}\binom{n\bmod p}{m\bmod p}\),而下指标 \(t\) 很小,有 \(\lfloor\frac tp\rfloor=0\),因此实际上直接带进去取模就是对的。

然后背包维护就是容易的了,对于复杂度,实际上单次转移 \(x\) 的信息量只有 \(n\log n\),这个东西是 \(\sum_{i=1}^n\frac ni\) 的经典复杂度,因此总的复杂度是 \(O(n^3\log n)\)

需要注意的是最后的根要多留一条边给基环树。

求无标号内向基环树方案数

这个东西要在环上做,那直接上 Burnside 引理。

\[|X/G|=\frac1{|G|}\sum_{g\in G}|X^g| \]

考虑记一个 \(F(n,m)\) 表示环上 \(n\) 个位置,每个位置的大小是 \(a_i\),且 \(\sum a_i=m\) 的方案数。那么枚举位置数量 \(h\) 和旋转置换环旋转的个数 \(t\),那么实际要统计的位置数是 \(\gcd(h,t)\),放置的点数是 \(\frac{n}{\frac{h}{\gcd(h,t)}}=\frac{n\gcd(h,t)}{h}\),于是上引理有:

\[tr_n=\sum_{h=1}^n\frac1h\sum_tF(\gcd(h,t),\frac{n\gcd(h,t)}{h}) \]

\(F\) 的方案数也好求了:

\[F(n,m)=\sum_{i=1}^mF(n-1,m-i) \]

Final Part

然后就是把若干基环树合成森林。这个合成的过程和一开始求树的方案数的方法是一致的:

\[ans_n=[x^n]\prod_{i=1}^n(\frac1{1-x^i})^{tr_i} \]

直接暴力做一下就好了。

下面给出代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 255, mod = 1e9 + 7;
inline void add(int &x, int y) {x = x + y >= mod ? x + y - mod : x + y;
}
int qpow(int x, int y) {int ans = 1;while (y) {if (y & 1) ans = 1ll * ans * x % mod;x = 1ll * x * x % mod;y >>= 1;}return ans;
}
int fac[N], inv[N];
int C(int n, int m) {if (n < m || n < 0 || m < 0) return 0;int ans = 1;for (int i = m + 1; i <= n; i++) ans = 1ll * ans * i % mod;return 1ll * ans * inv[n - m] % mod;
}int wn, wk;
int dp[N], f[N][N], num[N];int main() {fac[0] = 1;for (int i = 1; i < N; i++) fac[i] = 1ll * fac[i - 1] * i % mod;inv[N - 1] = qpow(fac[N - 1], mod - 2);for (int i = N - 2; ~i; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;cin >> wn >> wk;for (int i = 0; i <= wk; i++) f[0][i] = 1;dp[1] = 1;for (int n = 1; n <= wn; n++) {vector<pair<int, int>>v;int r = n, t = 0;while (r <= wn) ++t, v.emplace_back(t, C(t + dp[n] - 1, dp[n] - 1)), r += n;for (int x = wn; ~x; --x)for (int y = wk; ~y; --y)for (auto p : v) {int i = p.first, w = p.second;if (i * n <= x && i <= y) add(f[x][y], 1ll * f[x - i * n][y - i] * w % mod);}dp[n + 1] = f[n][wk];}for (int i = 1; i <= wn; i++) dp[i] = f[i - 1][wk - 1];memset(f, 0, sizeof f);f[0][0] = 1;for (int i = 1; i <= wn; i++)for (int j = 1; j <= wn; j++)for (int k = 1; k <= j; k++)add(f[i][j], 1ll * f[i - 1][j - k] * dp[k] % mod);for (int n = 1; n <= wn; n++)for (int h = 1; h <= n; h++) {int iv = qpow(h, mod - 2);for (int t = 1; t <= h; t++) {int g = __gcd(h, t);if (n * g % h == 0) add(num[n], 1ll * f[g][n * g / h] * iv % mod);}}memset(dp, 0, sizeof dp);dp[0] = 1;for (int n = 1; n <= wn; n++) {vector<pair<int, int>>v;int r = n, t = 0;while (r <= wn) ++t, v.emplace_back(t, C(t + num[n] - 1, num[n] - 1)), r += n;for (int x = wn; ~x; --x)for (auto p : v) {int i = p.first, w = p.second;if (i * n <= x) add(dp[x], 1ll * dp[x - i * n] * w % mod);}}cout << dp[wn] << '\n';return 0;
}
http://www.jsqmd.com/news/343059/

相关文章:

  • MySQL 中的逻辑读与物理读:深入理解 InnoDB 的 I/O 行为
  • 1.6 微分
  • 程序员为自己的工具命名时的彻底迷失【翻译】
  • 异步可以解决高并发请求?
  • weixin205微信小程序线上教育商城ssm(源码)_kaic
  • 4.2 OverDraw
  • 蚂蚁最新8B小模型拿下SOTA
  • go sync.oncevalue一个单例的更简实现
  • 1.10 CDN缓存
  • 86_Spring AI 干货笔记之 Chroma 向量存储
  • 检测性能直登顶!Mamba+YOLO优势互补,碾压所有传统YOLO!
  • 26. Mipmap
  • 大数据毕设项目:基于python+Hadoop的国家气象降雨量大数据分析系统(源码+文档,讲解、调试运行,定制等)
  • 顾比均线、顾比倒数线与趋势线相结合,加上仓位管理,可构成一套完整的趋势型交易系统 - Leone
  • 【无人机协同】基于matlab动态环境下多无人机系统的协同路径规划与防撞附Matlab代码
  • 【计算机毕业设计案例】基于Hadoop的某篮球队各个球员数据分析系统的设计与实现(程序+文档+讲解+定制)
  • 为什么新手总觉得 Modbus 很难?
  • 咖啡豆烘焙机厂家哪家实用性强?2026年榜单这几家靠谱企业值得关注! - 海棠依旧大
  • 排查某个软件是否安装,某个端口是否占用
  • 花 Opus 的钱买到 Sonnet?一行 Python 代码揭穿 API 服务商的“降本增效”骗局
  • 大数据BI工具的增强分析能力测评
  • 85_Spring AI 干货笔记之 Apache Cassandra 向量存储
  • 2026年2月中国境外券商投行机构推荐:看这5家公司就对了 - Top品牌推荐
  • 深入解析:【MySQL】数据库备份与恢复
  • 苹果 iPhone 14 Pro Max 高质量深度解析|配色外观|核心参数|屏幕与影像|续航充电|官方维修手册|二手验机清单
  • 【毕业设计】基于python+Hadoop的国家气象降雨量大数据分析系统(源码+文档+远程调试,全bao定制等)
  • 苹果 iPhone 15 高质量介绍:参数解析|体验要点|验机清单|维修手册重点
  • ubuntu卸载包
  • 程序员如何从 0 到 1 自己开发一个 AI Agent?
  • 03. PyTorch的使用