题目传送门(内部题8)


输入格式

一行三个整数$n,m,k$。


输出格式

一行一个整数表示答案。对$998244353$取模。


样例

样例输入

3 7 3

样例输出

6


数据范围与提示

对于10%的数据,$1\leqslant n,m,k\leqslant 10$。
对于40%的数据,$1\leqslant n,m,k\leqslant 1,000$。
对于70%的数据,$1\leqslant n,m,k\leqslant {10}^5$。
对于100%的数据,$1\leqslant n\leqslant {10}^9$,$1\leqslant n,k\leqslant {10}^7$。


题解

$20\%$算法:

如果$n>m$或$n<m\times k$那么一定没有方案,直接$puts("0");$即可。

时间复杂度:$\Theta(1)$。

期望的分:$0$分。

实际的分:$20$分。

$10\%$算法:

爆搜,枚举所有情况即可。

时间复杂度:$\Theta(n^k)$。

期望的分:$10$分。

实际的分:$10$分。

$40\%$算法:

考虑$DP$,设$dp[i][j]$为到第$i$个城市,一共用了$j$个建设队的方案数。

那么可以列出状态转移方程:$dp[i][j]=\sum \limits_{k=1}^{\min(k,m)}dp[i-1][j-k]$。

时间复杂度:$\Theta(n^3)$。

期望的分:$40$分。

实际的分:$40$分。

$100\%$算法:

考虑容斥,挡板法。

这个问题可以转化为,在$m$个物品中插入$n-1$个挡板,挡板不能插在一起,那么方案数就是$C_{m-1}^{n-1}$。

现在需要减去不合法的方案数,设至少有$i$个城市不合法,那么方案数就是$C_n^i\times C_{m-i\times k-1}^{n-1}$,可以理解为,我先将那$i\times k$个不合法的扔掉,再在$m-i\times k$里面选合法的即可。

利用容斥统计答案即可。

时间复杂度:$\Theta(m)$。

期望的分:$100$分。

实际的分:$100$分。


代码时刻

$20\%$算法:

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int main()
{
scanf("%d%d%d",&n,&m,&k);
if(n>m||n*k<m)puts("0");
return 0;
}

$40\%$算法:

#include<bits/stdc++.h>
using namespace std;
int dp[7000][7000];
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)dp[1][i]=1;
for(int i=2;i<=n;i++)
for(int j=i;j<=m;j++)
for(int l=1;l<=min(k,m);l++)
dp[i][j]=(dp[i][j]+dp[i-1][j-l])%998244353;
cout<<dp[n][m]<<endl;
return 0;
}

$100\%$算法:

#include<bits/stdc++.h>
using namespace std;
long long n,m,k;
long long jc[100000001],qsm[100000001];
long long ans;
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%998244353;
x=x*x%998244353;
y>>=1;
}
return res;
}
void pre_work()
{
jc[0]=1;
for(int i=1;i<=m;i++)
jc[i]=1LL*jc[i-1]*i%998244353;
for(int i=0;i<=m;i++)
qsm[i]=qpow(jc[i],998244351)%998244353;
}
long long cm(long long x,long long y)
{
return jc[x]*qsm[y]%998244353*qsm[x-y]%998244353;
}
long long lucas(long long x,long long y)
{
if(!y)return 1;
return cm(x%998244353,y%998244353)*lucas(x/998244353,y/998244353)%998244353;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
if(n>m||n*k<m){puts("0");return 0;}
pre_work();
long long flag=-1;
ans=jc[m-1]*qsm[n-1]%998244353*qsm[m-n]%998244353;
for(int i=1;i<=n;i++)
{
if(m-i*k<n)continue;
ans=(ans+flag*lucas(n,i)%998244353*lucas(m-i*k-1,n-1)+998244353)%998244353;
flag=-flag;
}
printf("%lld",(ans+998244353)%998244353);
return 0;
}

rp++

[CSP-S模拟测试]:建设城市(city)(组合数学+容斥)的更多相关文章

  1. 建设城市(city):组合数,容斥原理

    想模一大堆人呢.考场上AC的大仙. 估计没人想给这题好好写一个题解吧,因为它的确挺简单的... 但是它对我来说一点都不简单啊!!! 至少出题人用脚写题解的时候肯定认为这道题是送分题了 容斥,枚举至少有 ...

  2. [CSP-S模拟测试]:多维网格(组合数学+容斥)

    题目传送门(内部题138) 输入格式 输入数据第一行为两个整数$d,n$. 第二行$d$个非负整数$a_1,a_2,...,a_d$.     接下来$n$行,每行$d$个整数,表示一个坏点的坐标.数 ...

  3. 【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)

    [GDOI2016模拟3.16]幂 \(X\in[1,A],Y\in[1,B]\),问:\(x^y\)的不用取值个数. \(A,B\)都是\(10^9\)级别. 然后我们开搞. 首先,假设一个合法的\ ...

  4. HDU 6397 Character Encoding (组合数学 + 容斥)

    题意: 析:首先很容易可以看出来使用FFT是能够做的,但是时间上一定会TLE的,可以使用公式化简,最后能够化简到最简单的模式. 其实考虑使用组合数学,如果这个 xi 没有限制,那么就是求 x1 + x ...

  5. [BZOJ2839]:集合计数(组合数学+容斥)

    题目传送门 题目描述 .(是质数喔~) 输入格式 一行两个整数N,K. 输出格式 一行为答案. 样例 样例输入: 3 2 样例输出: 样例说明 假设原集合为{A,B,C} 则满足条件的方案为:{AB, ...

  6. [NOIP模拟测试7]visit 题解(组合数学+CRT+Lucas定理)

    Orz 因为有T的限制,所以不难搞出来一个$O(T^3)$的暴力dp 但我没试 据说有30分? 正解的话显然是组合数学啦 首先$n,m$可能为负,但这并没有影响, 我们可以都把它搞成正的 即都看作向右 ...

  7. 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】

    最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...

  8. codeforces 439 E. Devu and Birthday Celebration 组合数学 容斥定理

    题意: q个询问,每一个询问给出2个数sum,n 1 <= q <= 10^5, 1 <= n <= sum <= 10^5 对于每一个询问,求满足下列条件的数组的方案数 ...

  9. 【XSY2990】树 组合数学 容斥

    题目描述 同 Comb Avoiding Trees 不过只用求一项. \(n,k\leq {10}^7\) 题解 不难发现一棵 \(n\) 个叶子的树唯一对应了一个长度为 \(2n-2\) 的括号序 ...

随机推荐

  1. Shell脚本中单引号(‘)和双引号(“)的使用区别

    在Linux操作系统上编写Shell脚本时候,我们是在变量的前面使用$符号来获取该变量的值,通常在脚本中使用”$param”这种带双引号的格式,但也有出现使用'$param'这种带引号的使用的场景,首 ...

  2. VMWARE 克隆步骤

    克隆linux服务器点击设置 ->网络适配器->高级->MAC地址 重新生成一个 OK

  3. sql exist 和not exist(转载)

    exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:  select name from student where sex = 'm' and mark exists(select ...

  4. 分支结构 :if - else

    分支结构 :if - else 格式一: if(条件表达式){ 执行语句; } 格式二:二选一 if(条件表达式){ 执行语句1; }else{ 执行语句2; } 格式三: 多选一 if(条件表达式1 ...

  5. [APIO 2010] [LOJ 3144] 奇怪装置 (数学)

    [APIO 2010] [LOJ 3144] 奇怪装置 (数学) 题面 略 分析 考虑t1,t2时刻坐标相同的条件 \[\begin{cases} t_1+\lfloor \frac{t_1}{B} ...

  6. 运维脚本-elasticsearch数据迁移python3脚本

    elasticsearch数据迁移python3脚本 #!/usr/bin/python3 #elsearch 数据迁移脚本 #迁移工具路径 import time,os #下面命令是用到了一个go语 ...

  7. 在学习linux磁盘管理期间学习的逻辑卷管理笔记

    LVM(逻辑分区)的创建顺序:物理分区-物理卷-卷组-逻辑卷-挂载. 物理卷(Physical Volume,PV):就是指硬盘分区,也可以是整个硬盘或已创建的软RAID,是LVM的基本存储设备. 卷 ...

  8. 2019牛客暑期多校训练营(第四场) - K - number - dp

    https://ac.nowcoder.com/acm/contest/884/K 一开始整了好几个假算法,还好测了一下自己的样例过了. 考虑到300的倍数都是3的倍数+至少两个零(或者单独的0). ...

  9. python Calendar 模块导入及用法

    Calendar 是python 日历模块,此模块的函数都是日历相关的,例如打印某月的字符月历,星期之类的模块,下面剖析python Calendar 模块导入及用法. 1,python导入日历模块 ...

  10. ASP.NET中Literal控件的使用方法(用于向网页中动态添加内容)

    原文:https://www.jb51.net/article/82855.htm 可以将 Literal 控件用作网页上其他内容的容器.Literal 控件最常用于向网页中动态添加内容.简单的讲,就 ...