【CTS2019】随机立方体(容斥)

题面

LOJ

洛谷

题解

做这道题目的时候不难想到容斥的方面。

那么我们考虑怎么计算至少有\(k\)个极大值的方案数。

我们首先可以把\(k\)个极大值的位置给确定出来,方案数是\(\displaystyle {n\choose k}{m\choose k}{l\choose k}(k!)^3\),乘上\(k!\)是为了确定之间的顺序关系,即我们先确定\(xyz\)三维,然后把这三维要一一对应到点才行。假设这个值是\(w[k]\)。

剩下要填的是两个部分,一个是剩下的\((n-k)(m-k)(l-k)\)个没有什么影响的位置,以及和极大值有至少一维坐标相交的点。

所以方案数大概可以写成\({nml\choose nml-(n-k)(m-k)(l-k)}w[k]((n-k)(m-k)(l-k))!*h[k]\)的样子。

其中\(h[k]\)是分配极大值所在的\(k*k*k\)的这个小立方体上的数字的方案数。

为了方便\(V=nml,v[k]=V-(n-k)(m-k)(l-k)\)。

所以我们只需要考虑怎么分配这个挖掉\(k\)层的合法方案数。

首先每次确定掉一个极大值之后,我们就可以把它所在的这三个面直接丢掉,变成小一圈的一个立方体,而对于极大值而言,因为它要比所有同层的数都要大,所以我们从大往小,从内往外考虑填数。

首先最值的位置一定是三个面的交点,并且最值一定是当前所有剩余可填的数中的最大值。所以只需要确定剩下的数的数就行了,这个时候还有\(v[i]-1\)个数可以选,要选\(v[i]-v[i-1]-1\)个数,所以填进去的方案数就是\(\frac{(v[i]-1)!}{v[i-1]!}\)。

所以\(h[k]=h[k-1]*\frac{(v[k]-1)!}{v[k-1]!}\)。

所以\(\displaystyle h[k]=\prod_{i=1}^{k} \frac{(v[i]-1)!}{v[i-1]!}\)

然后把答案式掏出来,是:

\[\begin{aligned}
&\ \ \ \ \displaystyle {V\choose v[k]}w[k](V-v[k])!h[k]\\
&=\frac{V!}{v[k]!}w[k]h[k]\\
&=V!\frac{1}{v[k]!}w[k]h[k]\\
&=V!\frac{1}{v[k]!}w[k]\prod_{i=1}^k(v[i]-1)!\prod_{i=0}^{k-1}\frac{1}{v[i]!}\\
&=V!w[k]\prod_{i=1}^k \frac{1}{v[i]}
\end{aligned}\]

然后题目要求的是概率,所以和\(V!\)就没有关系了。

那么就只有后半部分。

这样子就很容易计算了。

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 5001000
#define MOD 998244353
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int jc[MAX],jv[MAX],inv[MAX];
int n,m,l,V,M,k,ans;
int v[MAX],w[MAX],s[MAX],invs[MAX];
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int C(int n,int m){return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
int main()
{
jc[0]=jv[0]=inv[0]=inv[1]=1;
for(int i=2;i<MAX;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<MAX;++i)jc[i]=1ll*jc[i-1]*i%MOD;
for(int i=1;i<MAX;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;
int T=read();
while(T--)
{
n=read();m=read();l=read();k=read();V=1ll*n*m%MOD*l%MOD;M=min(min(n,m),l);ans=0;
for(int i=1;i<=M;++i)v[i]=(V-1ll*(n-i)*(m-i)%MOD*(l-i)%MOD+MOD)%MOD;
for(int i=1;i<=M;++i)w[i]=1ll*C(n,i)*C(m,i)%MOD*C(l,i)%MOD*jc[i]%MOD*jc[i]%MOD*jc[i]%MOD;
s[0]=1;for(int i=1;i<=M;++i)s[i]=1ll*s[i-1]*v[i]%MOD;
invs[M]=fpow(s[M],MOD-2);for(int i=M-1;i;--i)invs[i]=1ll*invs[i+1]*v[i+1]%MOD;
for(int i=k,d=1;i<=M;++i,d=MOD-d)ans=(ans+1ll*d*C(i,k)%MOD*w[i]%MOD*invs[i])%MOD;
printf("%d\n",ans);
}
return 0;
}

【CTS2019】随机立方体(容斥)的更多相关文章

  1. [LOJ#3119][Luogu5400][CTS2019]随机立方体(容斥+DP)

    https://www.cnblogs.com/cjyyb/p/10900993.html #include<cstdio> #include<algorithm> #defi ...

  2. LOJ3119 CTS2019 随机立方体 概率、容斥、二项式反演

    传送门 为了方便我们设\(N\)是\(N,M,L\)中的最小值,某一个位置\((x,y,z)\)所控制的位置为集合\(\{(a,b,c) \mid a = x \text{或} b = y \text ...

  3. [CTS2019]随机立方体(容斥+组合数学)

    这题七次方做法显然,但由于我太菜了,想了一会发现也就只会这么多,而且别的毫无头绪.发现直接做不行,那么,容斥! f[i]为至少i个极值的方案,然后这里需要一些辅助变量,a[i]表示选出i个三维坐标均不 ...

  4. 题解-CTS2019随机立方体

    problem \(\mathtt {loj-3119}\) 题意概要:一个 \(n\times m\times l\) 的立方体,立方体中每个格子上都有一个数,如果某个格子上的数比三维坐标中至少有一 ...

  5. Luogu5400 CTS2019随机立方体(容斥原理)

    考虑容斥,计算至少有k个极大数的概率.不妨设这k个数对应的格子依次为(k,k,k)……(1,1,1).那么某一维坐标<=k的格子会对这些格子是否会成为极大数产生影响.先将这样的所有格子和一个数集 ...

  6. LOJ3120. 「CTS2019」珍珠 [容斥,生成函数]

    传送门 思路 非常显然,就是要统计有多少种方式使得奇数的个数不超过\(n-2m\).(考场上这个都没想到真是身败名裂了--) 考虑直接减去钦点\(n-2m+1\)个奇数之后的方案数,但显然这样会算重, ...

  7. 【题解】Luogu P5400 [CTS2019]随机立方体

    原题传送门 毒瘤计数题 我们设\(dp_i\)表示至少有\(i\)个极大数字的概率,\(ans_i\)表示恰好有\(i\)个极大数的概率,\(mi=Min(n,m,l)\) 易知: \[dp_i=\s ...

  8. 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)

    洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...

  9. [LibreOJ 3119]【CTS2019】随机立方体【计数】【容斥】

    Description Solution 记\(N=min(n,m,l)\) 首先考虑容斥,记\(f(i)\)为至少有i个位置是极大的,显然极大的位置数上界是N. 那么显然\(Ans=\sum\lim ...

随机推荐

  1. SpringBoot 整合Mybatis操作数据库

    1.引入依赖: <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId> ...

  2. Django框架 --序列化组件(serializer)

    一 .Django自带序列化组件 Django内置的serializers(把对象序列化成json字符串) from django.core import serializers from djang ...

  3. c# 根据一个给定经纬度的点和距离,搜索附近5公里范围的地点

    功能需求:需要查询一个站点(已知该站点经纬度)5公里范围内的其它站点. 方 法 一 :对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于5公里时,认为匹配(效率极其低下,耗时长). ...

  4. Python从零开始——条件控制语句

  5. 006-OpenStack-配仪表盘

    OpenStack-配仪表盘 [基于此文章的环境]点我快速打开文章 计算节点安装(compute1) 1.安装 yum install openstack-dashboard -y &> ...

  6. jenkins使用小技巧:jenkins构建出来的war/jar包如何带上SVN号?

    在实际使用过程中,一般会这样比如说打出来的包是 mypackage.jar, 但是每次打出来都是固定的 mypackage.jar如何来区分和上一个包的区别呢? 一般来说,会把打出来的包带上个 svn ...

  7. 基于 Docker 的 MySQL 主从复制搭建

    出处:https://www.jianshu.com/p/ab20e835a73f

  8. No archetypes currently available. The archetype list will refresh when the indexes finish updating

    配置方法: 1. 在卡住的而画面点击"config" 2. 点击"Add remote catalog", 然后设置华为云的maven仓库地址, 然后点击&qu ...

  9. 逆向工程文件example完美结合使用PageHelper分页插件及分页不成功原因

    原生的mybatis需要手写sql语句,项目数据库表多了之后,可以让你写sql语句写到手软,于是mybatis官方提供了mybatis-generator:mybatis逆向工程代码生成工具,用于简化 ...

  10. 如何有效的清理yum缓存

    如果遇到下面问题,请执行下面命令   yum clean all   #清除缓存