CF140E New Year Garland
题意
有 \(m\) 种小球,用这些小球装饰一棵 \(n\) 层的圣诞树,每层需要放置 \(a_i\) 个小球。在每一层中,相邻球颜色不同,且相邻两层球颜色集合不同,求装饰圣诞树的方案数,答案对 \(p\) 取模。
\(1\le n,m\le10^6,2\le p\le10^9,1\le a_i\le5000,\sum_{i = 1}^n a_i \le 10^7 \qquad \text{5s,250MB}\)
题解
贺 Daniel_lele 的题解。
先解决每一行的问题,每一行的要求是相邻球颜色不同,于是设 \(f_{i,j}\) 表示 \(i\) 个位置,用 \(j\) 种颜色的小球去填的方案数。状态转移就考虑是使用用过的颜色,还是没用过的颜色。
接下来考虑行与行之间的关系,若两行放的球颜色种数不同,那么集合更不可能相同;若颜色数相同,只需要在选颜色的时候方案减掉一种即可。设 \(g_{i,j}\) 表示第 \(i\) 层放 \(j\) 种颜色的球的方案数。由上述内容,首先枚举当前层颜色种数 \(j\),上一层颜色种数 \(k\),若 \(j \neq k\),则:\(g_{i,j} = f_{a_i,j}\times g_{i - 1,k} \times {m\choose j} \times j!\),反之 \(g_{i,j} = f_{a_i,j}\times g_{i - 1,k} \times \left({m\choose j - 1} - 1\right)\times j!\)。
\(k\) 的枚举是不必要的,记 \(h_i = \sum_{j = 1}^{a_i} g_{i,j}\),整理得到:
时间复杂度为 \(\mathcal{O}(n + \sum a)\)。
代码实现中,需要注意,因为模数不一定为质数,所以不能使用逆元求组合数,注意边界设为 \(1\)。
#include <bits/stdc++.h> using namespace std; const int N = 5e3 + 5,M = 1e6 + 5; #define int long long int n,m,P; int fac[N],C[N]; int a[M],L; int f[N][N],g[N],_g[N]; void init(){ fac[0] = 1; for (int i = 1;i < N;i++) fac[i] = 1ll * fac[i - 1] * i % P; C[0] = 1; for (int i = 1;i <= min(m,L);i++) C[i] = 1ll * C[i - 1] * (m - i + 1) % P; } signed main(){ cin >> n >> m >> P; for (int i = 1;i <= n;i++) cin >> a[i], L = max(L,a[i]); init(); f[0][0] = 1; for (int i = 1;i <= L;i++) for (int j = 0;j <= min(m,i);j++){ if (j > 1) (f[i][j] += f[i - 1][j] * (j - 1)) %= P; (f[i][j + 1] += f[i - 1][j]) %= P; } _g[0] = 1; for (int i = 1;i <= n;i++){ int s = 0; for (int j = 0;j <= a[i - 1];j++) (s += _g[j]) %= P; for (int j = 0;j <= a[i];j++){ g[j] = s * C[j] % P * f[a[i]][j] % P; if (j <= a[i - 1]) (g[j] += P - _g[j] * fac[j] % P * f[a[i]][j] % P) %= P; } for (int j = 0;j <= a[i];j++) _g[j] = g[j]; } int ans = 0; for (int i = 0;i <= a[n];i++) (ans += _g[i]) %= P; cout << ans; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!