题解-CTS2019随机立方体

problem

\(\mathtt {loj-3119}\)

题意概要:一个 \(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\) 个极大值的概率,答案即为:
\[ \sum_{i=k}^{\min\{n,m,l\}}(-1)^{i-k}\binom ik f[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\)

汇总一下,得到:
\[ f[i]=P_n^iP_m^iP_l^i\prod_{j=1}^i\frac 1{S_j}\\ =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;
}

转载于:https://www.cnblogs.com/penth/p/11389506.html

对不起,由于我是一个文本交互的模型,我无法提供图像内容或直接链接到具体的题解或解决方案。但是,我可以帮你理解CSP-J2019公交换乘问题的基本概念和解决策略,这通常涉及到数据结构、图论以及算法设计。 CSP-J2019中的公交换乘问题可能是一个典型的旅行商问题(Traveling Salesman Problem, TSP)变种,或者是寻找最优路径的问题,其中涉及到公交网络中不同站点之间的最短路径或最少换乘次数。解决此类问题通常需要使用动态规划、贪心算法或者一些启发式搜索算法,比如A*搜索或Dijkstra算法。 如果你需要了解题目的基本思路,可能会这样操作: 1. 建立一个图,节点代表公交站点,边代表两个站点之间的路线及其长度或换乘次数。 2. 对于每个节点,计算从起点到所有其他节点的最短路径,形成一个邻接矩阵或邻接表。 3. 使用动态规划方法,例如记忆化搜索,尝试所有可能的路径,每次选择当前未访问节点中距离最近的一个,直到遍历完所有节点并回到起点,记录下总的距离或换乘次数。 4. 为了优化,可以考虑使用启发式搜索策略,如用估算的总距离作为启发信息,优先探索看起来更优的路径。 如果你对具体解法有疑问,或者想了解某个步骤的详细操作,请告诉我,我会尽力解释。至于详细的题解,建议你查阅相关的代码库、论坛帖子或在线教程,它们通常会有文字描述和步骤示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值