HDOJ 7328 Snake —— 2023“钉耙编程”中国大学生算法设计超级联赛(5)(2023杭电多校第五场)

2023-11-18

题目链接

简要题意:题目相当于求 n n n个人排成 m m m个队伍,队伍内部有序,队伍之间无序,最长的长度不超过 k k k人的方案数。

题解:官方题解有多项式解法,作为多项式菜鸡,从来不写NTT的我写了一种广义容斥原理做法。

首先不难联想到小球入盒模型

n n n个相同的球放入 m m m个不同的盒子,每个盒子至少一个球的方案数,相当于在 n − 1 n-1 n1个空位中插入 m − 1 m-1 m1个隔板,有 C n − 1 m − 1 C_{n-1}^{m-1} Cn1m1种方案。

可以先排列,转化为小球入盒模型

1、 n n n个不同人排成一队,有 n ! n! n!种方案。接下来的步骤 n n n个人应该看作相同的。

2、 n n n个相同的人分成 m m m段,最长的一段不超过 k k k人的方案数。相当于 n n n个相同的球放入 m m m个不同的盒子,每个盒子不超过 k k k个球的方案数。

这是一个经典的小球入盒模型+广义容斥原理的应用。

根据广义容斥原理

假如有 n n n个不同的性质:
P k = P_k= Pk= 至少满足 k k k个性质的元素个数
Q k = Q_k= Qk= 恰好满足 k k k个性质的元素个数
Q k = ∑ i = 0 n − k ( − 1 ) i C k + i k P k + i Q_k=\sum\limits_{i=0}^{n-k}(-1)^iC_{k+i}^kP_{k+i} Qk=i=0nk(1)iCk+ikPk+i
特别地: Q 0 = P 0 − P 1 + P 2 − P 3 + . . . Q_0=P_0-P_1+P_2-P_3+... Q0=P0P1+P2P3+...

设该小球入盒问题的方案有 m m m个性质,第 i i i个性质是:第 i i i个盒子有大于 k k k个球

我们要求的是所有盒子的球都不超过 k k k个的方案数,即 Q 0 Q_0 Q0

P i = n P_i=n Pi=n个相同的球放入 m m m个不同的盒子,至少有 i i i个盒子有超过 k k k个球的方案数

P i P_i Pi方法如下:(为了方便,令 k ′ = k + 1 k'=k+1 k=k+1

2.1、选出 i i i个盒子,有 C m i C_m^i Cmi种选法。先在这 i i i个盒子中放入 k ′ k' k个球,它们最终必然 ≥ k ′ \geq k' k个球,而其他盒子随意安排,就达到了至少有 i i i个盒子大于 k ′ k' k个球的目的。

2.2、剩下的 n − i k ′ n-ik' nik个相同的球放入 m m m个不同的盒子,其中在上一步选中的 i i i个盒子至少放 0 0 0个,另外 m − i m-i mi个盒子至少放一个,有 C n − i k ′ + i − 1 m − 1 C_{n-ik'+i-1}^{m-1} Cnik+i1m1种方案(等价于先凭空借来 i i i个球,求出每盒至少 1 1 1球的方案数,得出方案后在 i i i个选中的盒子中收回一球)

得出 P i = C m i C n − i k ′ + i − 1 m − 1 P_i=C_m^iC_{n-ik'+i-1}^{m-1} Pi=CmiCnik+i1m1

根据广义容斥原理, Q 0 = ∑ i = 0 m ( − 1 ) i P i Q_0=\sum\limits_{i=0}^m (-1)^iP_i Q0=i=0m(1)iPi,注意到 m − 1 > n − i k ′ + i − 1 m-1>n-ik'+i-1 m1>nik+i1 i k > n − m ik>n-m ik>nm C n − i k ′ + i − 1 m − 1 C_{n-ik'+i-1}^{m-1} Cnik+i1m1无意义, P i = 0 P_i=0 Pi=0

3、当前 m m m个盒子是不同的,而按照题意盒子是相同的,因此要除以 m ! m! m!

综上, a n s = n ! m ! ∑ i = 0 min ⁡ ( ⌊ n − m k ⌋ , m ) ( − 1 ) i C m i C n − i ( k + 1 ) + i − 1 m − 1 ans=\frac{n!}{m!}\sum\limits_{i=0}^{\min (\lfloor \frac{n-m}{k}\rfloor,m)}(-1)^{i}C_m^iC_{n-i(k+1)+i-1}^{m-1} ans=m!n!i=0min(⌊knm,m)(1)iCmiCni(k+1)+i1m1,时间复杂度为 O ( n ) O(n) O(n),如果 i i i的循环上限搞不清楚,可以在组合数的函数里进行特判(代码里注释掉的部分),加上特判后就不用考虑组合数无意义的情况。比赛的时候加上这些特判通常可以避免一些细节上的错误,但是训练时应养成考虑完整的好习惯,避免给自己制造隐蔽的错误。有时候样例部分通过,可以考虑加上特判试一下,如果加上后顺利通过样例,说明很可能算上了一些无意义的组合数。

P S 1 PS_1 PS1:这题做法类似,有兴趣的可以做一下,同样可以广义容斥原理或者多项式快速幂:The 2021 CCPC Weihai Onsite Problem-M 810975

P S 2 PS_2 PS2:小球入盒模型可以根据球是否相同、盒是否相同、是否允许有空盒分为 8 8 8种情况,可以了解一下,三种需要斯特林数的我还不会。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e6+5;
const int mod=998244353;
ll fac[N],ifac[N];
ll qpow(ll a,ll b){
	ll s=1;
	for(;b;b>>=1){
		if(b&1)s=s*a%mod;
		a=a*a%mod;
	}
	return s;
}
ll C(int n,int m){
//	if(n<0||m<0||m>n)return 0;
	return fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
int n,m,k;
void work(){
	cin>>n>>m>>k;
	ll ans=0;
	int lim=min((n-m)/k,m);
	for(int i=0,f=1;i<=lim;++i){
		ans+=f*C(m,i)*C(n-i*(k+1)+i-1,m-1);
		ans%=mod;
		f*=-1;
	}
	ans=ans*fac[n]%mod*ifac[m]%mod;
	ans=(ans%mod+mod)%mod;
	cout<<ans<<"\n";
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	fac[0]=ifac[0]=1;
	for(int i=1;i<N;++i)fac[i]=fac[i-1]*i%mod;
	ifac[N-1]=qpow(fac[N-1],mod-2);
	for(int i=N-2;i;--i)ifac[i]=(i+1)*ifac[i+1]%mod;
	int T=1;
	cin>>T;
	while(T--){
		work();
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HDOJ 7328 Snake —— 2023“钉耙编程”中国大学生算法设计超级联赛(5)(2023杭电多校第五场) 的相关文章

随机推荐

  • 华为云原生之数据仓库服务GaussDB(DWS)的深度使用与应用实践

    一 GaussDB DWS 简介 什么是 GaussDB DWS 数据仓库服务 GaussDB DWS 是一种基于华为云基础架构和平台的在线数据处理数据库 提供即开即用 可扩展且完全托管的分析型数据库服务 GaussDB DWS 是基于华为
  • java内存工具VisualVM的简单使用以及与Idea集成

    一 idea集成 1 打开设置 windows File gt Setting MacOS Intelij Idea gt Preferences 1 2 打开插件仓库 Plugins gt Browers Repositrories 在这
  • SPI总线协议概述

    一 概述 SPI serial peripheral interface 是一种同步串行通信协议 由一个主设备和一个或多个从设备组成 主设备启动与从设备的同步通信 从而完成数据的交换 SPI是一种高速全双工同步通信总线 标准的SPI仅仅使用
  • 【Python】一个矩阵根据某一列选择大于或小于范围的数据

    data all data all data all 3 gt 54201 data all data all data all 3 lt 54220 上面就是根据数据的第3列 选取54201到54220的范围的数据
  • AD20的元件库及加载(一)

    开始时我们画的是元器件 元器件在后缀名为 的文件里画 以画电容为例 上图就是结果 画着简单 过程能学会很多 小伙伴们可能刚刚接触 不知道在哪找线 选择元器件不放 按住鼠标左键 并按下空格 即可旋转元器件的角度 每次旋转90度 电阻的两边的四
  • 福到了(15 分)

    L1 6 福到了 15 分 福 字倒着贴 寓意 福到 不论到底算不算民俗 本题且请你编写程序 把各种汉字倒过来输出 这里要处理的每个汉字是由一个 N N 的网格组成的 网格中的元素或者为字符 或者为空格 而倒过来的汉字所用的字符由裁判指定
  • 软件测试基础内容学习(二)之边界值分析法

    对限定边界规则设计测试点 边界值分析法 说明 1 边界范围节点 2 应用设计步骤 3 案例 4 适用场景 边界范围节点 选取正好等于 上点 刚好大于 刚好小于 离点 边界的值作为测试数据 内点 一般取最中间的点 在范围内的点 应用设计步骤
  • Python deque的用法介绍

    Python deque的用法介绍 deque 是Python标准库 collections 中的一个类 实现了两端都可以操作的队列 相当于双端队列 与Python的基本数据类型列表很相似 Python实现双端队列参考 https blog
  • JVM 一. 字节码与数据类型相关

    目录 一 字节码 数据类型相关 一 字节码 数据类型相关 字节码文件是跨平台的吗 是的 java虚拟机主要识别字节码文件 其实现在的java虚拟机已经不是单纯的java的 只要语言满足虚拟机的规范 都可以在这个虚拟机上运行 class文件中
  • 一、Kubernetes系列之介绍篇

    Kubernetes介绍 1 背景介绍 云计算飞速发展 IaaS PaaS SaaS Docker技术突飞猛进 一次构建 到处运行 容器的快速轻量 完整的生态环境 2 什么是kubernetes 首先 他是一个 全新的基于容器技术的分布式架
  • 微信回调模式配置企业服务器URL

    转载请标明出处 尊重他人劳动成果 谢谢 前几天微信推出了企业号 我就进去关注了一下 发现用途大大的多 就顺手整了一个测试号来试试 由于是新出的玩意儿 很多东西有文档也不到一定知道整 我这个配置就花了蛮久才找到失败的原因 最终是借用了浩然哥的
  • STL——queue模板类常见函数

    include
  • 【Python数据分析】Pandas按行遍历Dataframe

    Pandas按行遍历Dataframe的方法主要有两种 iterrows 和itertuples 具体用法如下 构建数据集 import pandas as pd import numpy as np N 20 dataset pd Dat
  • 08C++11多线程编程之unique_lock类模板

    08C 11多线程编程之unique lock类模板 前述 如果看懂了该篇文章 你对unique lock可以说随便使用 并且可以只看第5点的总结即可 1 unique lock概念 当不加参数时 和lock guard一样能自动上锁解锁
  • Unity 实现选框选中物体

    最近在看RTS游戏视频注意到了选框功能 就尝试做了一下 功能实现 脚本挂载到Camera上 要不然OnPostRender 函数无法调用 rectMat新建一个材质球 设置成默认的Sprites就可以了 using System Colle
  • Vue的安装和部署

    1 下载安装node js 官网下载地址 https nodejs org en 如果C盘较小 可以自定义安装到其他盘 解压完的目录如下 2 node v npm v 能看到版本号说明安装成功 3 在安装目录下 创建全局安装目录 node
  • Sqlite进阶之--附加数据库关联查询以及Pragma的相关使用

    数据库连接 基本的 Data Source c mydb db Version 3 此类库不支持版本 2 内存数据库 Data Source memory Version 3 New True SQLite 数据库通常存储在磁盘上 但数据库
  • 元组学习python复习资料

    a 第0个 2 3 d 倒1 1 倒1 2 这里我们区分好命名各元祖 1为第0个元祖 2为第1个元祖 csharp 再介绍一下元祖的概念 数据结构在python中包含 元祖 列表和字典 特点1 元祖一旦被创建不能被修改 a 第0个 2 3
  • 简洁直观的飞行器数学模型推导

    运动学方程 动力学方程 值得注意的是 对于非定轴和定轴转动 h r
  • HDOJ 7328 Snake —— 2023“钉耙编程”中国大学生算法设计超级联赛(5)(2023杭电多校第五场)

    题目链接 简要题意 题目相当于求 n n n个人排成 m m m个队伍 队伍内部有序 队伍之间无序 最长的长度不超过 k