首页 > 其他分享 >P5400 [CTS2019] 随机立方体 题解

P5400 [CTS2019] 随机立方体 题解

时间:2024-01-29 16:56:12浏览次数:36  
标签:frac 格子 limits int 题解 1ll CTS2019 P5400 prod

题目链接

点击打开链接

题目解法

参考 cmd 的博客

好复杂的推式子题,而且三维的对我来说好难想象/ll

首先二项式反演,把恰好 \(k\) 个变成求至少 \(i\) 个的方案数
令极大格子有至少 \(i\) 个的方案数为 \(f_i\),\(R=\min\{n,m,k\}\)
特判掉 \(k>R\) 答案为 \(0\)
根据二项式反演,答案为 \(\sum\limits_{i=k}^R f_i\binom{i}{k}(-1)^{i-k}\)

现在需要快速算出 \(\forall_{i=1}^R f_i\)
咋算?
令 \(g_x=(n-x)(m-x)(l-x),\;G_x=nml-g_x\)
考虑钦定 \(i\) 个极大格子,则有 \(g_i\) 个格子不受限
先考虑把这些不受限的格子给排好,首先在 \(nmk\) 个数中选出 \(g_i\) 个数,然后将这些数任意排列,所以方案数显然为 \(\binom{nml}{G_i}g_i!\)
再考虑受限的位置的选择,不难得到方案数为 \(\prod\limits_{j=1}^i(n-j)(m-j)(l-j)\),但这样钦定了顺序,所以要 \(\times \frac{1}{i!}\)

现在考虑最难的情况:有 \(i\) 个无序格子钦定是极大的,求和这 \(i\) 个格子牵连的 \(G_i\) 个格子合法排列的方案数
有些格子会被多个极大格限制,考虑如何使每个格子只被 \(1\) 个极大格限制
我们将极大格的值按照从小到大排列,分别是从外到里的每一层
这时我们惊奇地发现每个格子只被当前这一圈的极大格限制,这样就好做多了
说明需要借用一下 cmd 的图:点击打开图片
考虑从里往外排列每一个极大格,同时这个极大格限制的一圈格子都需要被排列
假设当前在考虑第 \(j\) 层,考虑之前的格子已经被扣掉了,现在只剩下 \(G_j\) 个位置,因为当前层的极大值一定是最大数,所以只要排列剩下的 \(g_{j-1}-g_{j}-1\) 个格子就可以了,所以方案数为 \(\prod\limits_{j=1}^i(G_j-1)^{\underline{g_{j-1}-g_{j}-1}}=\prod\limits_{j=1}^i\frac{(G_j-1)!}{(G_j-g_{j-1}+g_j+1)!}=\prod\limits_{j=1}^i\frac{(G_j-1)!}{G_{j-1}!}\)
因为极大格之间是无序的,我们只是人为钦定了顺序,所以方案数需要 \(\times i!\)

整理一下,\(f_i=\binom{nml}{G_i}g_i!\times \frac{1}{i!}\prod\limits_{j=1}^ig_j\times i!\prod\limits_{j=1}^i\frac{(G_j-1)!}{G_{j-1}!}\\ =(nml)!\frac{1}{G_i!}\times \prod\limits_{j=1}^ig_j\times \prod\limits_{j=1}^i\frac{(G_j-1)!}{G_{j-1}!}\)
因为最后要求概率,所以要除以 \((nml)!\)
所以 \(ans=\frac{1}{G_i!}\times \prod\limits_{j=1}^ig_j\times \prod\limits_{j=1}^i\frac{(G_j-1)!}{G_{j-1}!}\)
还是不太好做,考虑进一步化简
把 \(\frac{1}{G_i!}\) 放到 \(\prod\limits_{j=1}^i\frac{(G_j-1)!}{G_{j-1}!}\) 里面
所以 \(ans=\prod\limits_{j=1}^ig_j\frac{1}{G_0}\prod\limits_{j=1}^i\frac{(G_j-1)!}{G_j!}\\ =\prod\limits_{j=1}^ig_j\prod\limits_{j=1}^i\frac{1}{G_j}\)

求 \(\frac{1}{G_x}\) 可以通过线性求逆元的方法求
时间复杂度 \(O(T\min\{n,m,k\})\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
inline int read(){
    int FF=0,RR=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    return FF*RR;
}
const int N=5000010,P=998244353;
int fac[N],ifac[N];
int qmi(int a,int b){
    int res=1;
    for(;b;b>>=1){ if(b&1) res=1ll*res*a%P;a=1ll*a*a%P;}
    return res;
}
void init(int n){
    fac[0]=1;
    F(i,1,n) fac[i]=1ll*fac[i-1]*i%P;
    ifac[n]=qmi(fac[n],P-2);
    DF(i,n-1,0) ifac[i]=1ll*ifac[i+1]*(i+1)%P;
}
int binom(int x,int y){ return 1ll*fac[x]*ifac[y]%P*ifac[x-y]%P;}
int f[N],g[N],G[N];
void work(){
    int n=read(),m=read(),l=read(),k=read();
    int R=min(min(n,m),l);
    if(k>R){ puts("0");return;}
    int tot=1ll*n*m%P*l%P;
    G[0]=1;
    F(i,0,R){
        g[i]=1ll*(n-i)*(m-i)%P*(l-i)%P;
        if(i) G[i]=1ll*G[i-1]*(tot-g[i]+P)%P;
    }
    G[R]=qmi(G[R],P-2);
    DF(i,R-1,0) G[i]=1ll*G[i+1]*(tot-g[i+1]+P)%P;
    int mul=1;
    F(i,1,R) G[i]=1ll*G[i]*mul%P,mul=1ll*mul*(tot-g[i]+P)%P;
    f[0]=1;
    F(i,1,R) f[i]=1ll*f[i-1]*g[i-1]%P*G[i]%P;
    int ans=0;
    F(i,k,R){
        if((k-i)&1) ans=(ans-1ll*f[i]*binom(i,k)%P+P)%P;
        else ans=(ans+1ll*f[i]*binom(i,k))%P;
    }
    printf("%d\n",ans);
}
int main(){
    init(N-1);
    int T=read();
    while(T--) work();
    return 0;
}

标签:frac,格子,limits,int,题解,1ll,CTS2019,P5400,prod
From: https://www.cnblogs.com/Farmer-djx/p/17994867

相关文章

  • P1438 无聊的数列 题解
    背景看到题解都是差分,竟然还有建两颗线段树和二阶差分的大佬。我感到不理解,很不理解。题目正解本题正解很明显就是:线段树是的,你没有看错,就只有线段树。很显然我们直接按照线段树板题写就可以了,维护题目需要维护的,注意到只有单点查询,所以我们根本不需要维护区间和,对于区间来......
  • 洛谷P10114题解
    题意简述给定一个长度为\(n\)的序列,求\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}{((d_i\oplusd_j)+(d_i\otimesd_j))}\)。思维路径观察数据范围可以发现\(n\le2\times10^6\)而\(\sum\limitsd_i\le5\times10^7\),这说明\(d\)数组中的重复值较多,直接枚举数值可......
  • 洛谷题解-[ABC325E] Our clients, please wait a moment
    https://www.luogu.com.cn/problem/AT_abc325_e题目描述ある国には都市がNNN個あります。あなたは、都市111にある営業所から000個以上の都市を経由して都市NNNにある訪問先へ移動しようとしています。移動手段は社用車と電車の222種類があります。都市......
  • 洛谷P10115题解
    题意简述给定一个括号序列,求整个序列的美丽值最大。思维路径见到序列和权值,很容易想到需要用DP。我们定义\(f[i][j]\)表示第\(1\)到\(i\)个括号产生的美丽值最大值,其中\(j=0\)表示第\(i\)个括号本身不参与美丽值贡献,\(j=1\)表示第\(i\)个括号本身参与美丽值贡献......
  • B3929 [GESP202312 五级] 小杨的幸运数 题解
    因为一些众所周知的原因,不放代码。分享一种考场思路:\(a\le10^7\),顺序查找肯定会废,所以可以用一种类似埃氏筛的方法将所有满足条件的数标记一下,并将其加入一个答案数组\(a\)当中。然后每次查询只需要用lower_bound函数二分查找一下,假如找到了第\(i\)个:\(a_i=x\),直接......
  • P7324 [WC2021] 表达式求值 题解
    题目链接点击打开链接题目解法不错的题首先建出表达式树说实话我一开始不知道怎么建,但看了代码之后就懂了这里简单说一下:假如要对区间\([l,r]\)建树,分\(E_r=)\)和\(E_r\neq)\)的情况\(E_r=)\),找到匹配的左括号,递归下去建树\(E_r\neq)\),\(r\)可以作为单独的一个......
  • ABC338D 题解
    赛时怎么连这题都不会。再不练练思维真的就连普及题都不会做了啊。Solution题目来源:ABC338D(inAtcoder|in洛谷)。不妨先考虑应该断掉哪条边。首先我们发现,仅断掉一条边并不会让两个结点不可达,只会让我们从一个结点绕更远的路到达目标结点。如果我们要从结点\(u\)前往结点......
  • CF1070H 题解
    思路我们第一眼看题就发现每个字符串的长度在只有\(8\)。我们需要判断的是某个字符串是不是前面字符串的子串,因为长度太小,所以可以把字符串的每一个子串放到map里,再用一个map判断一个子串是否在当前字符串出现过,出现过就不能重复记。最后在用一个map记录一下每个子串对应......
  • CF1472F 题解
    前言只要题目给了图,你就要画图。思路首先,我们要明确一点:一个矩形,如果里面不存在任何被覆盖的方格,那么这个矩形是绝对可以被覆盖的。如果现在有一个点被覆盖了。那么必定要有一个长方形从这个点下方往后。然后继续在上方接长方形继续往后。直到出现了一个新节点被覆盖。......
  • 第一周题解
    第一周周报这一周是寒假训练的第一周,训练内容主要就是做牛客上的题单还有比赛,牛客上的题单还是比较痛苦的,因为牛客压根看不了测试用例,导致我事后想知道错的例子是什么都看不了。做第一题第二题还有倒数第三题有一两个例子一直都过不去。检查了很久的代码,一直是差一两个例子,就老是......