题目传送门:LOJ #3119

题意简述:

题目说的很清楚了。

题解:

记恰好有 \(i\) 个极大的数的方案数为 \(\mathrm{cnt}[i]\),则答案为 \(\displaystyle\frac{\mathrm{cnt}[k]}{(nml)!}\)。

“恰好”这个词非常的难受,我们考虑容斥:

记 \(\mathrm{f}[i]\) 为存在 \(i\) 个极大的数,且若恰好有 \(j\) 个极大的数,会被相应地统计 \(\displaystyle\binom{j}{i}\) 次的方案数。

则有:\(\displaystyle\mathrm{f}[i]=\sum_{j}\binom{j}{i}\mathrm{cnt}[j]\)。

根据二项式反演,有:\(\displaystyle\mathrm{cnt}[i]=\sum_{j}(-1)^{j-i}\binom{j}{i}\mathrm{f}[j]\)。

问题转化为求出每一个 \(\mathrm{f}[i]\)。


首先考虑以下事实:

  • 不会有超过 \(\min(n,m,l)\) 个极大的数。

  • 每两个极大的数必然不可能有任意一维的坐标相同,这是因为每个极大的数需要大于所有与它有任意一维坐标相同的点上的数。

  • 若至少存在 \(i\) 个极大的数,则有 \(i\) 行,\(i\) 列和 \(i\) 个纵截面被至少一个极大的数“控制”。

所以,剩余的 \((n-i)(m-i)(l-i)\) 个数是没有任何限制的,这是因为我们仅需保证至少存在 \(i\) 个极大的数。若剩下的数中又出现了极大的数也没关系,这实际上并不在考虑范围内。

又有,极大的数的条件仅和大小关系有关,而与数的绝对大小无关,所以可以看作乘上了一个“\(nml\) 取出 \((n-i)(m-i)(l-i)\) 个数进行排列的方案数”,即一个排列数的系数,而剩下的需要单独考虑。

但是先别着急,我们先写出目前得到的式子(下列式子中均将排列数写作下降幂的形式):

\[\mathrm{f}[i]=\left(n^{\underline{i}}m^{\underline{i}}l^{\underline{i}}\right)\times\left((nml)^{\underline{(n-i)(m-i)(l-i)}}\right)\times\mathrm{g}[i]
\]

第一个括号代表有顺序地选出(即一个排列)\(i\) 个三维坐标均互不相同的点,这个顺序即为之后的大小顺序。

第二个括号代表对无关点进行标号,也是一个排列数。

而 \(\mathrm{g}[i]\) 代表在剩下的 \(nml-(n-i)(m-i)(l-i)\) 个点中按照规定的大小顺序进行标号的方案数。


接下来我们考虑求出 \(\mathrm{g}[i]\):

让我们先考虑 \(i\) 个极大值中最大的那个,它的位置已经被确定了,它的值也被确定为可选的值中的最大的那一个,而所有与它有关联(有一维坐标相同)的位置都强制小于它。

但是,先等等!这些位置上的数,不一定只有最大值给予的一个限制,如果这个位置同时和其它极大值有关联,那么不能单纯用只最大值对其进行限制。

不过呢,其实这是没有影响的,我们只需要管那些“只和最大值有关联”的位置,若和其它极大值有关联,我们放到之后再去处理即可。

从这里就可以看出先考虑最大值的高明之处,因为越小的极大值的限制越严格,我们采取从大到小考虑的方式,就可以只考虑最后的限制。

而考虑完最大值以及“只和最大值有关联”的位置后,次大值的数值就应该为剩下的值中最大的那一个。

按照上述方式类推:对于最大的极大值,只要考虑那些和最大值有关联的部分,但是必须去除和“比最大值小的极大值”有关联的位置。

对于次大的,只要考虑和次大值有关联的部分,但是要去掉和“比次大值小的极大值”有关联的位置。

以此类推……

为了便于理解,我们展示 \(n=8,m=11,i=5\) 时的二维示例图(你也可以理解为 \(l=1\) 的三维情况):

因为极大值的位置与答案无关,为了方便,按照从小到大的顺序从左上角依次排下。

白色是无关位置,橙色是极大值所在位置,深绿色是仅和一个极大值有关联的位置,黄绿色是同时和两个极大值有关联的位置。

对于不是无关位置的格子,写上的数就表示它是在第几轮被考虑的。

可以看出,深绿色部分在考虑对应的极大值时的同一轮时就被统计,而黄绿色部分须等到对应的较小的极大值的同一轮才会被统计。

这张图的填数模式是浅显易懂的,很简单就能看出其中规律。

尝试写出其对应的 \(\mathrm{g}[i]\) 的值吧:\(\mathrm{g}[i]=69^{\underline{9}}\cdot 59^{\underline{11}}\cdot 47^{\underline{13}}\cdot 33^{\underline{15}}\cdot 17^{\underline{17}}\)。

每个下降幂(排列数)就对应着相应的轮数,例如第一轮中是 \(69\) 个数选出 \(9\) 个来排列。

进一步地,我们尝试写出形式化的公式(为了方便表述,定义记号 \(\varrho(x)=(n-x)(m-x)(l-x)\)):

对于某个 \(i\) 值的第 \(i-j+1\) 轮,换句话说,也就是图中从外往里数的第 \(j\) 层,

之前填完剩余的数的数量为 \(nml-(n-j)(m-j)(l-j)-1\) 个,即 \(\varrho(0)-\varrho(j)-1\),

需要填的位置的数量为 \((n-j+1)(m-j+1)(l-j+1)-(n-j)(m-j)(l-j)-1\) 个,即 \(\varrho(j-1)-\varrho(j)-1\)。

所以就需要乘上:从“剩余的数”中取出“需要填的位置”那么多数进行排列以填入位置中的方案数,也就是一个排列数。

则 \(\displaystyle\mathrm{g}[i]=\prod_{j=1}^{i}(\varrho(0)-\varrho(j)-1)^{\underline{\varrho(j-1)-\varrho(j)-1}}\)。

写成阶乘的形式就是 \(\displaystyle\mathrm{g}[i]=\prod_{j=1}^{i}\frac{(\varrho(0)-\varrho(j)-1)!}{(\varrho(0)-\varrho(j-1))!}\)。

这时就一目了然了,不难化成如下形式:

\[\mathrm{g}[i]=(\varrho(0)-\varrho(i)-1)!\prod_{j=1}^{i-1}\frac{1}{\varrho(0)-\varrho(j)}
\]


那么,将 \(\mathrm{g}[i]\) 代回 \(\mathrm{f}[i]\) 中吧!

\[\begin{aligned}\mathrm{f}[i]&=\left(n^{\underline{i}}m^{\underline{i}}l^{\underline{i}}\right)\times\left((nml)^{\underline{(n-i)(m-i)(l-i)}}\right)\times(\varrho(0)-\varrho(i)-1)!\prod_{j=1}^{i-1}\frac{1}{\varrho(0)-\varrho(j)}\\&=\left(n^{\underline{i}}m^{\underline{i}}l^{\underline{i}}\right)\frac{(nml)!}{(nml-\varrho(i))!}(nml-\varrho(i)-1)!\prod_{j=1}^{i-1}\frac{1}{nml-\varrho(j)}\\&=\left(n^{\underline{i}}m^{\underline{i}}l^{\underline{i}}\right)(nml)!\prod_{j=1}^{i}\frac{1}{nml-\varrho(j)}\end{aligned}
\]

则答案为:\(\displaystyle\frac{\mathrm{cnt}[k]}{(nml)!}=\frac{1}{(nml)!}\sum_{i}(-1)^{i-k}\binom{i}{k}\mathrm{f}[i]\)

注意到和 \(\mathrm{f}[i]\) 里面的 \((nml)!\) 抵消掉了,干脆两边都不写了吧:

\[\tilde{\mathrm{f}}[i]=\left(n^{\underline{i}}m^{\underline{i}}l^{\underline{i}}\right)\prod_{j=1}^{i}\frac{1}{nml-\varrho(j)}
\]

\[\mathbf{Ans}=\sum_{i}(-1)^{i-k}\binom{i}{k}\tilde{\mathrm{f}}[i]
\]


接下来就是最后的问题,我们需要在均摊 \(\mathcal{O}(1)\) 的时间内求出每个 \(\mathrm{f}[i]\)(\(0\le k\le\min(n,m,l)\))。

可以发现瓶颈在于求逆元上,只要用到这题的方法就可以了。

下面是代码:

#include <cstdio>

typedef long long LL;
const int Mod = 998244353;
const int MN = 5000005; void exgcd(int a, int b, int &x, int &y) {
if (!b) x = 1, y = 0;
else exgcd(b, a % b, y, x), y -= a / b * x;
}
inline int Inv(int a) {
int x, y;
exgcd(a < 0 ? a + Mod : a, Mod, x, y);
return x;
} int Invs[MN];
inline void Init(int N) {
Invs[1] = 1;
for (int i = 2; i <= N; ++i)
Invs[i] = -(LL)(Mod / i) * Invs[Mod % i] % Mod;
} int N, M, L, Q, K, Ans;
int Vals[MN], iVals[MN]; inline int R(int x) { return (LL)(N - x) * (M - x) % Mod * (L - x) % Mod; } int main() {
Init(5000000);
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d%d%d", &N, &M, &L, &K), Ans = 0;
Q = N < M ? N < L ? N : L : M < L ? M : L;
iVals[0] = 1;
for (int i = 1; i <= Q; ++i)
Vals[i] = R(0) - R(i),
iVals[i] = (LL)iVals[i - 1] * Vals[i] % Mod;
int iV = Inv(iVals[Q]);
for (int i = Q; i >= 1; --i)
iVals[i] = (LL)iV * iVals[i - 1] % Mod,
iV = (LL)iV * Vals[i] % Mod;
int C = 0, S = 1;
for (int i = 1; i <= Q; ++i) {
S = (LL)S * R(i - 1) % Mod * iVals[i] % Mod;
if (i == K) C = 1;
if (i > K) C = -(LL)C * i % Mod * Invs[i - K] % Mod;
Ans = (Ans + (LL)C * S) % Mod;
}
printf("%d\n", Ans < 0 ? Ans + Mod : Ans);
}
return 0;
}

感谢 @Winniechen 与我交流做法。

LOJ 3119: 洛谷 P5400: 「CTS2019 | CTSC2019」随机立方体的更多相关文章

  1. LOJ 3120: 洛谷 P5401: 「CTS2019 | CTSC2019」珍珠

    题目传送门:LOJ #3120. 题意简述: 称一个长度为 \(n\),元素取值为 \([1,D]\) 的整数序列是合法的,当且仅当其中能够选出至少 \(m\) 对相同元素(不能重复选出元素). 问合 ...

  2. 「CTS2019 | CTSC2019」随机立方体 解题报告

    「CTS2019 | CTSC2019」随机立方体 据说这是签到题,但是我计数学的实在有点差,这里认真说一说. 我们先考虑一些事实 如果我们在位置\((x_0,y_0,z_0)\)钦定了一个极大数\( ...

  3. LOJ #3119「CTS2019 | CTSC2019」随机立方体 (容斥)

    博客链接 里面有个下降幂应该是上升幂 还有个bk的式子省略了k^3 CODE 蛮短的 #include <bits/stdc++.h> using namespace std; const ...

  4. 【LOJ】#3119. 「CTS2019 | CTSC2019」随机立方体

    题解 用容斥,算至少K个极大值的方案数 我们先钦定每一维的K个数出来,然后再算上排列顺序是 \(w_{k} = \binom{n}{k}\binom{m}{k}\binom{l}{k}(k!)^3\) ...

  5. LOJ #3119. 「CTS2019 | CTSC2019」随机立方体 组合计数+二项式反演

    好神的一道计数题呀. code: #include <cstdio> #include <algorithm> #include <cstring> #define ...

  6. LOJ3119. 「CTS2019 | CTSC2019」随机立方体 二项式反演

    题目传送门 https://loj.ac/problem/3119 现在 BZOJ 的管理员已经不干活了吗,CTS(C)2019 和 NOI2019 的题目到现在还没与传上去. 果然还是 LOJ 好. ...

  7. Loj #3124. 「CTS2019 | CTSC2019」氪金手游

    Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...

  8. 「CTS2019 | CTSC2019」氪金手游 解题报告

    「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...

  9. LOJ 2743(洛谷 4365) 「九省联考 2018」秘密袭击——整体DP+插值思想

    题目:https://loj.ac/problem/2473 https://www.luogu.org/problemnew/show/P4365 参考:https://blog.csdn.net/ ...

随机推荐

  1. 洛谷p3385【模板】负环

    最近很久没怎么写最短路的题导致这个题交了好多遍 AC率是怎么下来的自己心里没点数 SPFA虽然臭名昭著但是他可以用来判负环 如果一个点进队的次数大于等于n说明存在负环 这道题一开始memset我给di ...

  2. DP问题(3) : hdu 1080

    题目转自hdu 1080,题目传送门 题目大意: 不想翻译! 解题思路: 其实就是一道变异的求lcs(Longest common subsequence 最长公共子序列)的题 不过,它的依据是下面这 ...

  3. mod35云掩膜产品用法

    在网上一直没找到一个明确说怎么用MOD35产品的,都是说去看用户手册,第一次看了过一段时间我又忘记怎么搞了,赶紧记下来. 而且现在才发现第一次自己搞的都弄错了. 简单的判断是否是云,只要读取mod35 ...

  4. Salesforce 开发整理(九) 开发中使用的一些小技巧汇总[持续更新]

    1.查询一个对象下所有字段 当需要查询一个对象所有字段进行复制或其他操作,可以使用一段拼接的语句来查询 String query = 'select '; for(String fieldApi : ...

  5. AtCoder Grand Contest 036 简要题解

    从这里开始 比赛目录 Problem A Triangle 考虑把三角形移到和坐标轴相交,即 然后能够用坐标比较简单地计算面积,简单构造一下就行了. Code #include <bits/st ...

  6. Swagger简单介绍

    一句话介绍 Swagger Swagger是一个接口文档生成工具,同时提供接口测试调用的辅助功能. 关于 Swagger Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原 ...

  7. mybatis 的 dao 接口跟 xml 文件里面的 sql 是如何建立关系的?

    mybatis 会先解析这些xml 文件,通过 xml 文件里面的命名空间 (namespace)跟dao 建立关系:然后 xml 中的每段 sql 会有一个id 跟 dao 中的接口进行关联. 那么 ...

  8. Maven依赖以及项目创建

    目录: 1. Maven依赖.Eclipse中使用Maven.生命周期 1.1 Maven依赖 1.2 Eclipse中使用Maven 2. 依赖排除.通过Maven整合多个Maven 2.1 依赖排 ...

  9. spring boot中的日志入门

    日志通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节.但是,这丝毫不影响它在任何一个系统中的重要地位. 报警系统与日志系统的关系 为了保证服务的高可用,发现问题一定要及时,定位 ...

  10. lua中,两种json和table互转方法的效率比较

    lua中json和table的互转,是我们在平时开发过程中经常用到的.比如: 在用lua编写的服务器中,如果客户端发送json格式的数据,那么在lua处理业务逻辑的时候,必然需要转换成lua自己的数据 ...