Viva La Vida(Fried-Chicken's Version)

Viva La Vida(Fried-Chicken's Version)

题目描述

鸡王国有 n 个城市,编号分别为 1,2,n,初始城市之间没有任何道路连接。为了灾后重建,鸡国王决定在一些城市之间修建双向道路,于是他请首席工程师瓦爵鸡根据王国的地形地貌特征,对在城市之间修建道路的费用进行了评估,以 ai,j(1i<jn) 表示在城市 i 和城市 j 之间修建双向道路的费用。对于每一个城市,鸡国王会选择该城市到其它 n1 个城市中费用最低的那条道路修建(如果这条道路已经存在,则什么也不做)。最后鸡国王会计算鸡王国的连通分量的个数,定义两个城市在一个连通分量中当且仅当这两个城市可以通过上述方法修建的双向道路互相到达。

然而,工程师瓦爵鸡是坑蒙拐骗的高手,他并不会评估修建费用!他只会随机生成一个长度为 n×(n1)2 的排列 p1,p2,,pn×(n1)2,即等概率地从 n×(n1)2! 个排列中选择一个,并将该排列赋值给 ai,j(1i<jn)。现在鸡国王请你帮忙计算,按照上述方法修建道路后鸡王国的连通分量个数的期望。你需要将答案对 998244353 取模后输出。

输入描述:

每个测试文件均包含多组测试数据。第一行输入一个整数 T(1T105) 代表数据组数,每组测试数据描述如下: 在一行上输入一个整数 n(2n108) 代表鸡王国的城市数量。

输出描述:

对于每一组测试数据,输出一行一个整数代表答案。可以证明答案可以表示为一个不可约分数 pq,为了避免精度问题,请直接输出整数 (p×q1modM) 作为答案,其中 M=998244353q1 是满足 q×q11(modM) 的整数。

更具体地,你需要找到一个整数 x[0,M) 满足 x×qM 取模等于 pM 取模。例如,如果最终计算得到的结果是 65,我们能够找到,598946613×5=2994733065,对 998244353 取模后恰好等于分子 6,所以 598946613 是需要输出的答案。可以证明答案一定可以通过该方法进行表示。

示例1

输入

4
2
3
114514
1919810

输出

1
1
197053580
498126582

备注:

样例二的 6 种可能情况如下图所示,红色表示最终被修建的道路。以左上角的图片为例,顶点 1 到其它城市最低的修建道路费用 1、顶点 2 到其它城市最低的修建道路费用是 1、顶点 3 到其它城市最低的修建道路费用是 2。最终,六种情况中联通块的个数都为 1,因此联通块个数的期望是 1

 

解题思路

  关键性质:对于任意一组边权,得到的图一定不存在环。反证法,假设图中存在一个环,其中环上权值最大的边为 (u,v)。因为边 (u,v) 的存在,说明一定是从 uv 修建得到的。由于环的大小至少为 3,假设环上与边 (u,v) 相邻的两条边分别为 (x,u)(v,y)。如果 (u,v)u 修建得到,由于 (x,u) 的权值小于 (u,v),因此 u 不可能修建 (u,v)。同理由于 (v,y) 的权值小于 (u,v) 因此 v 不可能修建 (u,v)。因此边 (u,v) 不存在,从而环不存在,矛盾。

  由此可得图一定是由若干棵树构成(即森林)。初始时连通块的数量就是点的数量,每添加一条没有重复的边连通块数量减一,因此连通块的数量就是点数减去边数。又因为添加边的总数量恰好是点的数量,因此点数减去没有重复的边数等于重复的边数。所以连通块的数量等于重复的边数。为此我们可以等价于求重边的期望。

  当某一条边 (u,v) 被重复选择,意味着 (u,v) 同时是连接 uv 的权值最小的边。连接 uv 的总边数为 2n3,由于排列是等概率随机选择,因此边 (u,v) 是这 2n3 条边中权值最小的概率就是 12n3。又因为在完全图中每条边的分析都是独立且相同的,因此每条边是重边的概率都是 12n3。由于共有 Cn2 条边,因此重边的期望就是 Cn22n3

  另外也可以从贡献法的思路来分析,考虑每条边对重边期望的贡献是多少。在 n×(n1)2! 种边权中,假设 (u,v) 的边权是 i,为了使得 (u,v)2n3 条边中权值最小的,其余的 2n4 条边的权值只能从 [i+1,Cn2] 中选,方案数为 ACn2i2n4。剩下的 Cn22n+3 条边的方案数则为 (Cn22n+3)!。因此 (u,v) 是重边的方案数就是 (Cn22n+3)!i=1Cn22n+4ACn2i2n4,对期望的贡献就是(Cn22n+3)!i=1Cn22n+4ACn2i2n4Cn2!

  可以推导证明上式的结果等于 12n3,详细见附录。因此 Cn2 条边对答案的贡献同样是 Cn22n3

  AC 代码如下,时间复杂度为 O(Tlogmod)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int mod = 998244353;

int qmi(int a, int k) {
    int ret = 1;
    while (k) {
        if (k & 1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        k >>= 1;
    }
    return ret;
}

void solve() {
    int n;
    cin >> n;
    cout << n * (n - 1ll) % mod * qmi(4 * n - 6, mod - 2) % mod << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

 

附录

  证明(Cn22n+3)!i=1Cn22n+4ACn2i2n4Cn2!=12n3

  首先有组合数求和公式 i=0kCi+aa=Ck+a+1a+1。组合意义上的解释就是从集合 {1,2,,k+a+1} 中选出 a+1 元素的所有可能方式。我们可以把这个过程拆分为先选择一个最大的元素 i+a+1,然后再从 {1,2,,i+a} 中选出 a 个元素,那么方案数就是 Ci+aa。因此总的方案数就是 i=0kCi+aa

  为了方便令 m=Cn2,因此

i=1m2n+4Ami2n4(2n4)!i=1m2n+4Cmi2n4=(2n4)!i=0m2n+3Ci+2n42n4=(2n4)!Cm2n3=(2n4)!m!(2n3)!(m2n+3)!=m!(2n3)(m2n+3)!

  所以

(Cn22n+3)!i=1Cn22n+4ACn2i2n4Cn2!=(m2n+3)!m!m!(2n3)(m2n+3)!=12n3

  得证。

 

参考资料

  2025牛客寒假算法基础集训营6 出题人题解:https://ac.nowcoder.com/discuss/1455225

  题解 | 2025牛客寒假算法基础集训营6 D题题解:https://www.nowcoder.com/discuss/718887583539879936

posted @   onlyblues  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2024-02-13 D. Lonely Mountain Dungeons
2024-02-13 E. Space Harbour
2023-02-13 D. Moscow Gorillas
2023-02-13 B. Fedya and Array
2022-02-13 飞行员兄弟
Web Analytics
点击右上角即可分享
微信分享提示