原题传送门

毒瘤计数题

我们设\(dp_i\)表示至少有\(i\)个极大数字的概率,\(ans_i\)表示恰好有\(i\)个极大数的概率,\(mi=Min(n,m,l)\)

易知:

$$dp_i=\sum_{j=i}^{mi} ans_j \tbinom{j}{i}$$

由二项式反演得:

$$ans_i=\sum_{j=i}^{mi} dp_j \tbinom{j}{i} (-1)^{j-i}$$

我就不在此证明(实际是我不会证明)

所以我们只需要快速求出dp数组,就珂以快速得到答案

我们需要利用以下结论:

1.我们会发现当\((x_0,y_0,z_0)\)是极大值点时,\(x=x_0,y=y_0,z=z_0\)三个平面上不珂能再有极大值点且都填上小于\((x_0,y_0,z_0)\)的值,剩下的就像是一个\((n-1)(m-1)(l-1)\)的子问题

2.我们所填的数值是离散化后相对的数值,也就是说,只要选出的数离散化后满足某关系,就是一种合法的状态

设\(g_i\)表示选定了\(i\)个极大值点后影响到的平面的交集的方块数,由结论2可知这时候贡献要乘上\(\tbinom{N}{g_i}(N=nml)\)(下文\(N\)与此时的\(N\)同义)

易知\(g_i=N-(n-i)(m-i)(l-i)\)

设\(f_i\)表示选定\(i\)个极大值点的方案数,易知:

$$f_i=\prod_{j=0}^{i-1}(n-j)(m-j)(l-j)$$

设\(h_i\)表示填充选定了\(i\)个极大值点后影响到的平面的交集的方案数,易知:

$$

\begin{align}

h_i

& = \frac{(g_i-1)!}{g_{i-1}!} \times h_{i-1} \

& = \prod_{j=0}^{i-1} \frac{(g_{j+1}-1)!}{g_j!}

\end{align
}

\[
#### 我们这是就珂以求出$dp_i \times N!$了,即至少有$i$个极大数字的种类数,那么$dp_i$也就珂以求出

#### \]

\begin{align}

dp_i
N!

& = \tbinom{N}{g_i} f_i h_i (N-g_i)! \

& = \frac{N!}{g_i!(N-g_i)!}f_i \prod_{j=0}^{i-1} \frac{(g_{j+1}-1)!}{g_j!} (N-g_i)! \

& = N! f_i \prod_{j=1}i(g_j-1)!\prod_{j=0}i\frac{1}{g_j!} \

& = N! f_i \prod_{j=1}^i\frac{1}{g_j}

\end{align*}

\[
#### $$dp_i=f_i \prod_{j=1}^i\frac{1}{g_j}\]

这样我们就能快速求出答案了,复杂度为\(O(T Min(n_i,m_i,l_i))\)

#include <bits/stdc++.h>
#define N 5000005
#define mod 998244353
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
return a<b?a:b;
}
inline int fastpow(register int a,register int b)
{
int res=1;
while(b)
{
if(b&1)
res=1ll*res*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return res;
}
int T,n,m,l,k,mi,ans;
int fac[N],invf[N];
int f[N],g[N],invg[N],dp[N];
inline int C(register int m,register int n)
{
return 1ll*fac[m]*invf[n]%mod*invf[m-n]%mod;
}
int main()
{
fac[0]=1;
for(register int i=1;i<N;++i)
fac[i]=1ll*fac[i-1]*i%mod;
invf[N-1]=fastpow(fac[N-1],mod-2);
for(register int i=N-1;i;--i)
invf[i-1]=1ll*invf[i]*i%mod;
T=read();
while(T--)
{
n=read(),m=read(),l=read(),k=read();
mi=Min(n,Min(m,l));
if(k>mi)
{
puts("0");
continue;
}
f[0]=1;
for(register int i=0;i<mi;++i)
{
g[i]=1ll*(n-i)*(m-i)%mod*(l-i)%mod;
f[i+1]=1ll*f[i]*g[i]%mod;
}
int fg=1,tot=g[0];
g[mi]=0;
for(register int i=1;i<=mi;++i)
{
g[i]=(0ll+tot+mod-g[i])%mod;
fg=1ll*fg*g[i]%mod;
}
invg[mi]=fastpow(fg,mod-2);
for(register int i=mi;i;--i)
invg[i-1]=1ll*invg[i]*g[i]%mod;
for(register int i=1;i<=mi;++i)
dp[i]=1ll*f[i]*invg[i]%mod;
ans=0;
for(register int i=k;i<=mi;++i)
if((i-k)&1)
ans=(0ll+ans+mod-1ll*C(i,k)*dp[i]%mod)%mod;
else
ans=(0ll+ans+1ll*C(i,k)*dp[i]%mod)%mod;
write(ans),puts("");
}
return 0;
}

【题解】Luogu P5400 [CTS2019]随机立方体的更多相关文章

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

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

  2. 题解-CTS2019随机立方体

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

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

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

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

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

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

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

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

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

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

    [CTS2019]随机立方体(容斥) 题面 LOJ 洛谷 题解 做这道题目的时候不难想到容斥的方面. 那么我们考虑怎么计算至少有\(k\)个极大值的方案数. 我们首先可以把\(k\)个极大值的位置给确 ...

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

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

  9. [题解] Luogu P5446 [THUPC2018]绿绿和串串

    [题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...

随机推荐

  1. C++中vector的使用总结

    vector简单说明 vector也是一个容器,并且是个顺序容器.顺序容器有可变长数组vector.双向链表list.双端队列deque. 顺序容器的定义,是因为容器元素的位置和他们的值大小无关,也就 ...

  2. OpenVSwitch

    参考: https://opengers.github.io/openstack/openstack-base-use-openvswitch/ 这篇原理部分就不贴出来了,请自行参考上文,并根据自行实 ...

  3. SVN cornerstone Commit\Update 提示xxx is already Locked解决方法

    点击菜单栏“working copy” 点“clean”: 或者,如下图: 右击,点击“clean”,问题解决.

  4. seqtk 一款快速处理fasta/fastq 文件的小程序

    seqtk 的 GitHub 官网 https://github.com/lh3/seqtk 安装 git clone https://github.com/lh3/seqtk.git cd seqt ...

  5. 记一次phpmyadmin 4.8.1 远程文件包含漏洞(BUUCTF web)

    题目很简单,一个滑稽 打开源码,发现存在source.php文件 于是访问文件,发现出现一串php源码 提示存在hint.php,于是访问发现一句话 flag not here, and flag i ...

  6. BIND配置

    一,简介 相对于存储和大数据领域,CDN是一个相对小的领域,但行行出状元,BIND就是CDN领域的蝉联N届的状元郎.BIND是一款非常常用的DNS开源服务器,全球有90%的DNS用BIND实现.值得一 ...

  7. encode_chunked=req.has_header('Transfer-encoding'))问题解决方法

    Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.6/lib/ ...

  8. Python3+mitmproxy安装使用教程(Windows)(转载)

    mitmproxy 是用于MITM的proxy,MITM中间人攻击.说白了就是服务器和客户机中间通讯多增加了一层.跟Fiddler和Charles最大的不同就是,mitmproxy可以进行二次开发,尤 ...

  9. vue动态绑定class的几种方式

    对象方法 -最简单的绑定(这里的active加不加单引号都可以,以下也一样都能渲染) :class="{ 'active': isActive }" 判断是否绑定一个active ...

  10. Go安装配置和《菜鸟教程之Go语言教程》学习笔记

    Go 语言是一种让代码分享更容易的编程语言 菜鸟教程-Go语言教程(这个教程过于基础,体现不了Go的特性和强大.) 下载/安装Go语言 https://golang.org/dl/ Mac OS X ...