「CTS2019 | CTSC2019」随机立方体
时间:2020-05-12
本文章向大家介绍「CTS2019 | CTSC2019」随机立方体,主要包括「CTS2019 | CTSC2019」随机立方体使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
「CTS2019 | CTSC2019」随机立方体
传送门
题解
首先看到这个恰好\(k\)个可以很轻松的想到容斥,这个东西就是一个二项式反演.
接着我们思考如何求恰好\(i\)个合法的个数?设\(dp_i\)为所求,
\[f_i=\prod_{j=0}^{i-1}(n-j)(m-j)(l-j)
\\
g_i=n\times m\times l-(n-i)\times (m-i)\times (l-i)
\\
h_i=h_{i-1}\times \frac{(g_i-1)!}{g_{i-1}!}
\\
\begin{align}
dp_i&=\binom{n\times m\times l}{g_i}\times f_i\times h_i\times (n\times m\times l-g_i)!
\\
&=(n\times m\times l)!\times f_i\times \prod_{j=0}^{i}\frac{1}{g_j!}\prod_{j=1}^i(g_j-1)
\\
&=(n\times m\times l)!\times f_i\times \prod_{j=1}^{i}\frac{1}{g_j}
\end{align}
\]
具体解释就是\(f_i\)表示恰好\(i\)个的放置方案数,\(g_i\)表示可以放置的位置的数量,\(h_i\)表示极大数中数放置的可能方案数.
这个求的是方案数,把\((n\times m \times l)!\)去掉就是概率了,然后直接对\(dp_i\)二项式反演即可.注意最后那个分数可以线性求逆元求.
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define REP(a,b,c) for(int a=b;a<=c;a++)
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
typedef pair<int,int> pii;
#define mp make_pair
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=5000010,Mod=998244353;
int qpow(int a,int b){int ret=1;while(b){if(b&1)ret=1ll*ret*a%Mod;b>>=1;a=1ll*a*a%Mod;}return ret;}
int n,m,l,k,f[N],g[N],ifac[N],M,dp[N],inv[N],fac[N];
void init()
{
fac[0]=fac[1]=ifac[0]=ifac[1]=inv[0]=inv[1]=1;
for(int i=2;i<=5000000;i++)
fac[i]=1ll*fac[i-1]*i%Mod,
inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod,
ifac[i]=1ll*ifac[i-1]*inv[i]%Mod;
}
int C(int n,int m){return 1ll*fac[n]*ifac[m]%Mod*ifac[n-m]%Mod;}
int main()
{
int T=gi();init();
while(T--)
{
n=gi();m=gi();l=gi();k=gi();f[0]=ifac[0]=1;
M=min(n,min(m,l));
if(M<k){puts("0");continue;}
for(int i=0;i<M;i++)f[i+1]=1ll*f[i]*(n-i)%Mod*(m-i)%Mod*(l-i)%Mod;
for(int i=1;i<=M;i++)g[i]=(1ll*n*m%Mod*l%Mod-1ll*(n-i)*(m-i)%Mod*(l-i)%Mod+Mod)%Mod;
int now=1;
for(int i=1;i<=M;i++)now=1ll*now*g[i]%Mod;now=qpow(now,Mod-2);
for(int i=M;i;i--){int pre=g[i];g[i]=now;now=1ll*now*pre%Mod;}
for(int i=1;i<=M;i++)dp[i]=1ll*f[i]*g[i]%Mod;
int ans=0;
for(int i=k,f=1;i<=M;i++,f=Mod-f)
ans=(ans+1ll*f*C(i,k)%Mod*dp[i]%Mod)%Mod;
printf("%d\n",ans);
}
return 0;
}
原文地址:https://www.cnblogs.com/fexuile/p/12878256.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 2020年8月26日更新WINDOWS服务器同时安装多个版本的MYSQL的方法,MQYSQL5和MQYSQL8的共存。
- python 自动化测试(3):数据库连接与使用
- 微信小程序实战开发二:微信小程序 WEUL组件之 画廊组件
- 关于Cookie和Session
- 微信小程序实战开发一:在小程序中使用useExtendedLib方法引入官方UI
- python 自动化测试(4):日志类封装
- 微信小程序实战开发三:小程序之全局配置APP.JSON之底部菜单栏tabBar
- python 自动化测试(5):页面基类封装
- 微信小程序实战开发四:小程序获取用户信息流程及信息存储方式解析
- python 自动化测试(6):jar包调用
- 微信小程序实战开发五:使用自定义组件配置一个通用的图片轮播组件。
- 亿级流量系统如何玩转 JVM
- 微信小程序实战开发六:使用weui-flex创建一个可自由配置的布局组件。
- JDBCJava连接MySql数据库
- Python中的集合