【CTS2019】随机立方体(容斥)
【CTS2019】随机立方体(容斥)
题面
题解
做这道题目的时候不难想到容斥的方面。
那么我们考虑怎么计算至少有\(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]!}\)
然后把答案式掏出来,是:
&\ \ \ \ \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】随机立方体(容斥)的更多相关文章
- [LOJ#3119][Luogu5400][CTS2019]随机立方体(容斥+DP)
https://www.cnblogs.com/cjyyb/p/10900993.html #include<cstdio> #include<algorithm> #defi ...
- LOJ3119 CTS2019 随机立方体 概率、容斥、二项式反演
传送门 为了方便我们设\(N\)是\(N,M,L\)中的最小值,某一个位置\((x,y,z)\)所控制的位置为集合\(\{(a,b,c) \mid a = x \text{或} b = y \text ...
- [CTS2019]随机立方体(容斥+组合数学)
这题七次方做法显然,但由于我太菜了,想了一会发现也就只会这么多,而且别的毫无头绪.发现直接做不行,那么,容斥! f[i]为至少i个极值的方案,然后这里需要一些辅助变量,a[i]表示选出i个三维坐标均不 ...
- 题解-CTS2019随机立方体
problem \(\mathtt {loj-3119}\) 题意概要:一个 \(n\times m\times l\) 的立方体,立方体中每个格子上都有一个数,如果某个格子上的数比三维坐标中至少有一 ...
- Luogu5400 CTS2019随机立方体(容斥原理)
考虑容斥,计算至少有k个极大数的概率.不妨设这k个数对应的格子依次为(k,k,k)……(1,1,1).那么某一维坐标<=k的格子会对这些格子是否会成为极大数产生影响.先将这样的所有格子和一个数集 ...
- LOJ3120. 「CTS2019」珍珠 [容斥,生成函数]
传送门 思路 非常显然,就是要统计有多少种方式使得奇数的个数不超过\(n-2m\).(考场上这个都没想到真是身败名裂了--) 考虑直接减去钦点\(n-2m+1\)个奇数之后的方案数,但显然这样会算重, ...
- 【题解】Luogu P5400 [CTS2019]随机立方体
原题传送门 毒瘤计数题 我们设\(dp_i\)表示至少有\(i\)个极大数字的概率,\(ans_i\)表示恰好有\(i\)个极大数的概率,\(mi=Min(n,m,l)\) 易知: \[dp_i=\s ...
- 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)
洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...
- [LibreOJ 3119]【CTS2019】随机立方体【计数】【容斥】
Description Solution 记\(N=min(n,m,l)\) 首先考虑容斥,记\(f(i)\)为至少有i个位置是极大的,显然极大的位置数上界是N. 那么显然\(Ans=\sum\lim ...
随机推荐
- jQuery 的58种事件方法你都用过了吗
jQuery 事件方法 事件方法触发或将函数附加到所选元素的事件处理程序. 下表列出了用于处理事件的所有jQuery方法. 方法 描述 bind() 在3.0版中已弃用. 请改用on()方法.将事件处 ...
- flink WaterMark之TumblingEventWindow
1.WaterMark,翻译成水印或水位线,水印翻译更抽象,水位线翻译接地气. watermark是用于处理乱序事件的,通常用watermark机制结合window来实现. 流处理从事件产生,到流经s ...
- To B产品,业务方全程蒙蔽怎么搞?
这是发生在很久前的事,那会我还是产品实习生. 今天和业务部门进行需求审核,对的是公司内部SAAS系统的采购模块.怎么说呢?就是觉得不专业吧 辛辛苦苦把原 ...
- 转:oracle 体系结构
前几天面试的时候面试官才问过我ORACLE的体系结构,让我在一张白纸上画出来.回头想想当时答得还不错,大部分内容都描述出来了,呵呵,刚才在网上看到一篇讲解ORACLE体系结构的文章,觉得不错,转过来存 ...
- vue 开发系列(九) VUE 动态组件的应用
业务场景 我们在开发表单的过程中会遇到这样的问题,我们选择一个控件进行配置,控件有很多中类型,比如文本框,下来框等,这些配置都不同,因此需要不同的配置组件来实现. 较常规的方法是使用v-if 来实现, ...
- [TCP/IP] ping traceroute和TTL
1.Time To Live是生存时间的意思,就是说这个ping的数据包能在网络上存在多少时间.当我们对网络上的主机进行ping操作的时候,我们本地机器会发出一个数据包,数据包经过一定数量的路由器传送 ...
- 【转载】CMake 两种变量原理
原文地址:https://cslam.cn/archives/c9f565b5.html 摘要: 本文记录一下 CMake 变量的定义.原理及其使用.CMake 变量包含 Normal Variabl ...
- 便宜的回文 (USACO 2007)(c++)
2019-08-21便宜的回文(USACO 2007) 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 追踪每头奶牛的去向是一件棘手的任 ...
- Appium基础:appium相关API
1.获取信息类: 1.1 获取当前界面的组件: driver.currentActivity(); //获取当前界面的activity,可用于断言是否跳转到预期的activity 1.2 获取当前页面 ...
- python27期day04:列表、元组、range、作业题。
1.for循环套for循环: for i in "abc": for x in "egf: print(x) 结果是:e g f e g f e g f 2.99乘法表 ...