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

[2023杭电多校5 1005] Snake (生成函数)

题意

n n n 个标号为 1 , 2 , ⋯ , n 1,2,\cdots,n 1,2,,n 的球,放到 m m m 个无标号盒子 (盒内顺序有标号),且每个盒子球数不超过 k k k,求方案数对 998 244 353 998\,244\,353 998244353 取模。

1 ≤ m , k ≤ n ≤ 1 0 6 1 \le m,k \le n \le 10 ^ 6 1m,kn106

分析:

考虑每个盒子内球的生成函数 ∑ i = 1 k x i \sum\limits_{i = 1} ^ {k}x ^ i i=1kxi,那么 m m m 个盒子的生成函数就为 ( ∑ i = 1 k x i ) m \left( \sum\limits_{i = 1} ^ {k}x ^ i\right) ^ m (i=1kxi)m,那么方案数就为第 n n n 项系数

由于球带标号,所以需要对答案全排列,也就是乘 n ! n! n!,又由于盒子不带标号,所以要对答案除 m ! m! m!,那么答案为

n ! m ! × [ x n ] ( ∑ i = 1 k x i ) m \frac{n!}{m!} \times [x ^ n]\left( \sum\limits_{i = 1} ^ {k}x ^ i\right) ^ m m!n!×[xn](i=1kxi)m

1 0 6 10 ^ 6 106 用多项式快速幂会超时,考虑

( ∑ i = 1 k x i ) m = x m ( ∑ i = 0 k − 1 x i ) m = x m ( 1 − x k ) m ( 1 − x ) m \left( \sum\limits_{i = 1} ^ {k}x ^ i\right) ^ m= x ^ m \left( \sum\limits_{i = 0} ^ {k - 1}x ^ i\right) ^ m = x ^ m \frac{(1 -x ^ k)^m}{(1 - x) ^ m} (i=1kxi)m=xm(i=0k1xi)m=xm(1x)m(1xk)m

转为求 [ x n − m ] ( 1 − x k ) m ( 1 − x ) m [x^{n - m}] \dfrac{(1 -x ^ k)^m}{(1 - x) ^ m} [xnm](1x)m(1xk)m 其中

( 1 − x k ) m = ∑ i = 0 m ( m i ) × ( − 1 ) i × x i × k 1 ( 1 − x ) m = ∑ i = 0 ∞ ( m − 1 + i m − 1 ) × x i (1 - x ^ k) ^ m = \sum_{i = 0} ^ {m}\binom{m}{i} \times (-1) ^ i \times x ^ {i \times k} \\ \frac{1}{(1 - x) ^ m} = \sum_{i = 0} ^ {\infty} \binom{m - 1 + i}{m - 1} \times x ^ i (1xk)m=i=0m(im)×(1)i×xi×k(1x)m1=i=0(m1m1+i)×xi

于是枚举第一个式子的 i i i,那么只需要求第二个式子的 n − m − i × k n - m - i \times k nmi×k 项系数即可。预处理组合数即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int mod = 998244353;
template<class T>
T power(T a, int b) {T res = 1;for (; b; b /= 2, a *= a) {if (b % 2) {res *= a;}}return res;
}
template<int mod>
struct ModInt {int x;ModInt() : x(0) {}ModInt(i64 y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}ModInt &operator+=(const ModInt &p) {if ((x += p.x) >= mod) x -= mod;return *this;}ModInt &operator-=(const ModInt &p) {if ((x += mod - p.x) >= mod) x -= mod;return *this;}ModInt &operator*=(const ModInt &p) {x = (int)(1LL * x * p.x % mod);return *this;}ModInt &operator/=(const ModInt &p) {*this *= p.inv();return *this;}ModInt operator-() const {return ModInt(-x);}ModInt operator+(const ModInt &p) const {return ModInt(*this) += p;}ModInt operator-(const ModInt &p) const {return ModInt(*this) -= p;}ModInt operator*(const ModInt &p) const {return ModInt(*this) *= p;}ModInt operator/(const ModInt &p) const {return ModInt(*this) /= p;}bool operator==(const ModInt &p) const {return x == p.x;}bool operator!=(const ModInt &p) const {return x != p.x;}ModInt inv() const {int a = x, b = mod, u = 1, v = 0, t;while (b > 0) {t = a / b;swap(a -= t * b, b);swap(u -= t * v, v);}return ModInt(u);}ModInt pow(i64 n) const {ModInt res(1), mul(x);while (n > 0) {if (n & 1) res *= mul;mul *= mul;n >>= 1;}return res;}friend ostream &operator<<(ostream &os, const ModInt &p) {return os << p.x;}friend istream &operator>>(istream &is, ModInt &a) {i64 t;is >> t;a = ModInt<mod>(t);return (is);}int val() const {return x;}static constexpr int val_mod() {return mod;}
};
using Z = ModInt<mod>;
vector<Z> fact, infact;
void init(int n) {fact.resize(n + 1), infact.resize(n + 1);fact[0] = infact[0] = 1;for (int i = 1; i <= n; i ++) {fact[i] = fact[i - 1] * i;}infact[n] = fact[n].inv();for (int i = n; i; i --) {infact[i - 1] = infact[i] * i;}
}
Z C(int n, int m) {if (n < 0 || m < 0 || n < m) return Z(0);return fact[n] * infact[n - m] * infact[m];
}
void solve() {int n, m, k;cin >> n >> m >> k;Z ans;for (int i = 0; i <= m; i ++) {Z f = i & 1 ? Z(-1) : Z(1);ans += f * C(m, i) * C(n - k * i - 1, m - 1);}cout << ans * fact[n] / fact[m] << "\n";
}
signed main() {init(1e6);cin.tie(0) -> sync_with_stdio(0);int T;cin >> T;while (T --) {solve();}
}
http://www.lryc.cn/news/106362.html

相关文章:

  • 【MyBtis】各种查询功能
  • H5打包封装小程序系统开发
  • SpringBoot集成jasypt,加密yml配置文件
  • 【C++】模板(初阶)
  • windows下的txt文档,传到ubuntu后,每行后面出现^M,怎么处理?
  • LabVIEW FPGA开发实时滑动摩擦系统
  • Prometheus服务器、Prometheus被监控端、Grafana、Prometheus服务器、Prometheus被监控端、Grafana
  • 常见的锁策略(面试八股文)
  • SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL、保活包
  • 【phaser微信抖音小游戏开发005】画布上添加图片
  • 【设计模式——学习笔记】23种设计模式——外观模式Facade(原理讲解+应用场景介绍+案例介绍+Java代码实现)
  • 消息队列 -提供上层服务接口
  • maven引入本地jar包的简单方式【IDEA】【SpringBoot】
  • 【爬虫逆向案例】某易云音乐(评论)js逆向—— params、encSecKey解密
  • 【uni-app】【Android studio】手把手教你运行uniapp项目到Android App
  • 多线程(JavaEE初阶系列6)
  • shell清理redis模糊匹配的多个key
  • 【电网异物检测硕士论文摘抄记录】电力巡检图像中基于深度学习的异物检测方法研究
  • C++共享数据的保护
  • MyBatisPlus学习记录
  • 如何开启一个java微服务工程
  • libhv之hio_t分析
  • C语言的转义字符
  • 【腾讯云 Cloud Studio 实战训练营】CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手!
  • Pandas时序数据分析实践—时序数据集
  • use strict 是什么意思?使用它区别是什么?
  • 常见OOM异常分析排查
  • kubernetes网络之网络策略-Network Policies
  • 交换机VLAN技术和实验(eNSP)
  • 8.Winform界面打包成DLL提供给其他的项目使用