题解-CTS2019随机立方体
problem
题意概要:一个 \(n\times m\times l\) 的立方体,立方体中每个格子上都有一个数,如果某个格子上的数比三维坐标中至少有一维相同的其他格子上的数都要大的话,我们就称它是极大的。将 \(n\times m\times l\) 的排列随机填入这些格子,求恰有 \(k\) 个极大的数的概率。\(T\) 组数据。
\(T\le 10,\ 1\le n,m,l\le 5\times 10^6,\ 1\le k \le 100\),时限 \(5s\)
Solution
为啥CTS比APIO难这多?我果然还是不会数数呐
根据这一个月来的数数经验……发现:
- 求答案为 \(k\) (权值)的题:应该是转换成 “答案小于等于 \(k\)” 减去 “答案小于等于 \(k-1\)”。
- 求恰好 \(k\) 个(数量)的题:应该是转换成 “至少有 \(k\) 个”,再利用二项式反演得到答案。
所以这里设 \(f[i]\) 表示至少有 \(i\) 个极大值的概率,答案即为:
\]
问题转换成求 \(f[i]\)。
首先选出这 \(i\) 个确定的极大值的坐标,系数为:\(P_n^iP_m^iP_l^i\)(考虑顺序,后边要用到)
定义一个坐标 \((x_0,y_0,z_0)\) 的控制范围为 三个平面 \(x=x_0,y=y_0,z=z_0\) 的并(所以极大值的定义即为:该点权值 为 其控制范围上点的权值最大值)
问题转化为求这 \(i\) 个坐标的控制范围的并内,有多少种安排数字顺序(不是权值而是大小关系,因为目前已经选出了这些坐标,并且现在要求的是概率,而非方案数)的方法,使得对于每个选定的坐标,其都为自己控制范围内的最大值。
直接考虑这个问题不好考虑,需要找到突破口,而这里的突破口就是 “这些控制范围的并内,最大值一定是一个极大值”。由于我们在选出这 \(i\) 个坐标的时候,已经考虑了顺序问题,所以若 这\(i\)个极大值控制范围的并 大小为 \(S_i\),则这件事情发生的概率为 \(\frac 1{S_i}\),并且发生这件事情后,所有只被这个极大值控制的点都没用了,则将问题转化为选出 \(i-1\) 个坐标的情况,如此递归,计算得到的权值为 \(\prod_{j=1}^i\frac 1{S_j}\)
至于如何计算 \(S_i\),可以发现取全局减多余可得 \(S_i=nml-(n-i)(m-i)(l-i)\),或是直接考虑容斥 \(S_i=(nm+nl+ml)i-(n+m+l)i^2+i^3\)
汇总一下,得到:
=P_n^iP_m^iP_l^i\prod_{j=1}^i\frac 1{nml-(n-i)(m-i)(l-i)}\\
Ans=\sum_{i=k}^{\min\{n,m,l\}}(-1)^{i-k}\binom ikf[i]\\
=\sum_{i=k}^{\min\{n,m,l\}}(-1)^{i-k}\binom ikP_n^iP_m^iP_l^i\prod_{j=1}^i\frac 1{nml-(n-i)(m-i)(l-i)}
\]
这个式子是线性的,但由于后头那个 \(\prod\) 需要求逆元,所以复杂度为 \(O(\min\{n,m,l\}\log p)\),如此能过 \(80\)。
考虑到这个东西实际上是要求每一个前缀积的逆元,和求阶乘逆元类似,可以先求出整个前缀积的逆元,再从后面往前乘,复杂度 \(O(\min\{n,m,l\}+\log p)\)
设:
\[a_i=nml-(n-i)(m-i)(l-i)\\
b_i=\prod_{j=1}^ia_j\\
c_i=\frac 1{b_i}
\]可以 \(O(1)\) 得到 \(a_i\),\(O(n)\) 得到 \(b_i\),\(O(\log p)\) 得到 \(c_n=\frac 1{b_n}\),\(O(n)\) 得到 \(c_i=c_{i+1}\cdot a_{i+1}\)
Code
//loj-3119
#include <cstdio>
typedef long long ll;
const int N = 5001010, p = 998244353;
int fac[N], ifac[N];
int coe[N], h[N], ih[N];
int n, m, l, k;
inline int qpow(int A, int B) {
int res = 1; while(B) {
if(B&1) res = (ll)res * A%p;
A = (ll)A * A%p, B >>= 1;
} return res;
}
int main() {
fac[0] = 1;
for(int i=1;i<N;++i) fac[i] = (ll)fac[i-1] * i%p;
ifac[N-1] = qpow(fac[N-1], p-2);
for(int i=N-1;i;--i) ifac[i-1] = (ll)ifac[i] * i%p;
int T; scanf("%d",&T);
while(T--) {
scanf("%d%d%d%d", &n, &m, &l, &k);
if(n > m) n ^= m, m ^= n, n ^= m;
if(n > l) n ^= l, l ^= n, n ^= l;
const int s2 = ((ll)n*m + (ll)m*l + (ll)n*l)%p, s1 = n+m+l;
for(int i=h[0]=1;i<=n;++i) {
coe[i] = (s2 - (ll)s1 * i + (ll)i*i + (ll)p*p)%p * i%p;
h[i] = (ll)h[i-1] * coe[i]%p;
}
ih[n] = qpow(h[n], p-2);
for(int i=n;i;--i) ih[i-1] = (ll)ih[i] * coe[i]%p;
const int nml_k = (ll)fac[n] * fac[m]%p * fac[l]%p * ifac[k]%p;
int Ans = 0;
for(int i=k;i<=n;++i) {
int vl = (ll)nml_k * fac[i]%p * ifac[i-k]%p * ifac[n-i]%p * ifac[m-i]%p * ifac[l-i]%p;
vl = (ll)vl * ih[i]%p;
if(i-k&1) vl = p - vl;
(Ans += vl) >= p && (Ans -= p);
}
printf("%d\n", Ans);
}
return 0;
}
题解-CTS2019随机立方体的更多相关文章
- 【题解】Luogu P5400 [CTS2019]随机立方体
原题传送门 毒瘤计数题 我们设\(dp_i\)表示至少有\(i\)个极大数字的概率,\(ans_i\)表示恰好有\(i\)个极大数的概率,\(mi=Min(n,m,l)\) 易知: \[dp_i=\s ...
- LOJ3119 CTS2019 随机立方体 概率、容斥、二项式反演
传送门 为了方便我们设\(N\)是\(N,M,L\)中的最小值,某一个位置\((x,y,z)\)所控制的位置为集合\(\{(a,b,c) \mid a = x \text{或} b = y \text ...
- [LOJ#3119][Luogu5400][CTS2019]随机立方体(容斥+DP)
https://www.cnblogs.com/cjyyb/p/10900993.html #include<cstdio> #include<algorithm> #defi ...
- Luogu5400 CTS2019随机立方体(容斥原理)
考虑容斥,计算至少有k个极大数的概率.不妨设这k个数对应的格子依次为(k,k,k)……(1,1,1).那么某一维坐标<=k的格子会对这些格子是否会成为极大数产生影响.先将这样的所有格子和一个数集 ...
- [CTS2019]随机立方体(容斥+组合数学)
这题七次方做法显然,但由于我太菜了,想了一会发现也就只会这么多,而且别的毫无头绪.发现直接做不行,那么,容斥! f[i]为至少i个极值的方案,然后这里需要一些辅助变量,a[i]表示选出i个三维坐标均不 ...
- 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)
洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...
- 【CTS2019】随机立方体(容斥)
[CTS2019]随机立方体(容斥) 题面 LOJ 洛谷 题解 做这道题目的时候不难想到容斥的方面. 那么我们考虑怎么计算至少有\(k\)个极大值的方案数. 我们首先可以把\(k\)个极大值的位置给确 ...
- 「CTS2019 | CTSC2019」随机立方体 解题报告
「CTS2019 | CTSC2019」随机立方体 据说这是签到题,但是我计数学的实在有点差,这里认真说一说. 我们先考虑一些事实 如果我们在位置\((x_0,y_0,z_0)\)钦定了一个极大数\( ...
- 【loj3119】【CTS2019】随机立方体
题目 一个 $ n m l $ 的立方体等概率填入 $ 1-nml $ ; 定义一个位置是极大的当且仅当这个位置比三位坐标的至少一维与之相等的位置的值都大. 询问极大值恰好有\(k\)个的 ...
随机推荐
- 【Java文件】按UTF-8编码读取文本文件(逐行方式),排序,打印到控制台
代码: package findJavaMemberFunction; import java.io.BufferedReader; import java.io.FileInputStream; i ...
- intel 性能分析
分析memory bound,etc https://software.intel.com/en-us/articles/intel-vtune-amplifier-tutorials
- linux下phpmailer发送邮件出现SMTP ERROR: Failed to connect to server: (0)错误
转自:https://www.cnblogs.com/raincowl/p/8875647.html //Create a new PHPMailer instance $mail = new PHP ...
- Linux_CentOS 打包压缩和别名管理
Linux 打包压缩命令 目前 linux 中打包和压缩的命令很多,最常用的方法有 zip.gzip.bzip2.xz.tar 1.zip 压缩包 1.制作 zip -r public.zip pub ...
- TypeScript泛型类 - 把类作为参数类型的泛型类
/* TypeScript泛型类 - 把类作为参数类型的泛型类 */ /* 泛类:泛型可以帮助我们避免重复的代码以及对不特定数据类型的支持(类型校验),下面我们看看把类当做参数的泛型类 1.定义个类 ...
- Spring cloud微服务安全实战-6-9sentinel之熔断降级
来讲一下降级规则 服务会互相调用,服务A会有一些服务之间的依赖. 假设服务D的响应时间变长了.A调用D就会卡住了. 熔断,某一个服务出现问题,会把服务拖死.如果A出现,会把依赖A的那些服务拖死. 主要 ...
- PAT 甲级 1066 Root of AVL Tree (25 分)(快速掌握平衡二叉树的旋转,内含代码和注解)***
1066 Root of AVL Tree (25 分) An AVL tree is a self-balancing binary search tree. In an AVL tree, t ...
- java 特殊字符处理
// 去除富文本中的html标签 // <p>段落替换为换行 content = content.replaceAll("<p .*?>", "\ ...
- Nginx 504响应超时
1.问题分析 nginx访问出现504 Gateway Time-out,一般是由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时. ...
- Jquery操作表格多出一个内容行
目录 前言 需求 如何监听每一行点击,获取点击id 前后端 问题更新,ajax异步带来的问题 废弃使用HTML拼接 前言 我的前端实在是太差劲了,导致Jquery操作表格多出一个内容行,这个功能我都做 ...