首页 > 其他分享 >D. Good Trip

D. Good Trip

时间:2024-02-03 14:34:31浏览次数:22  
标签:Good frac cdot sum int right Trip left

D. Good Trip

There are $n$ children in a class, $m$ pairs among them are friends. The $i$-th pair who are friends have a friendship value of $f_i$.

The teacher has to go for $k$ excursions, and for each of the excursions she chooses a pair of children randomly, equiprobably and independently. If a pair of children who are friends is chosen, their friendship value increases by $1$ for all subsequent excursions (the teacher can choose a pair of children more than once). The friendship value of a pair who are not friends is considered $0$, and it does not change for subsequent excursions.

Find the expected value of the sum of friendship values of all $k$ pairs chosen for the excursions (at the time of being chosen). It can be shown that this answer can always be expressed as a fraction $\dfrac{p}{q}$ where $p$ and $q$ are coprime integers. Calculate $p\cdot q^{-1} \bmod (10^9+7)$.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 5 \cdot 10^4$). Description of the test cases follows.

The first line of each test case contains $3$ integers $n$, $m$ and $k$ ($2 \le n \le 10^5$, $0 \le m \le \min \Big(10^5$, $ \frac{n(n-1)}{2} \Big)$, $1 \le k \le 2 \cdot 10^5$) — the number of children, pairs of friends and excursions respectively.

The next $m$ lines contain three integers each — $a_i$, $b_i$, $f_i$ — the indices of the pair of children who are friends and their friendship value. ($a_i \neq b_i$, $1 \le a_i,b_i \le n$, $1 \le f_i \le 10^9$). It is guaranteed that all pairs of friends are distinct.

It is guaranteed that the sum of $n$ and sum $m$ over all test cases does not exceed $10^5$ and the sum of $k$ over all test cases does not exceed $2 \cdot 10^5$.

Output

For each test case, print one integer — the answer to the problem.

Example

input

4
100 0 24
2 1 10
1 2 1
3 1 2
2 1 1
5 2 4
1 2 25
3 2 24

output

0
55
777777784
40000020

Note

For the first test case, there are no pairs of friends, so the friendship value of all pairs is $0$ and stays $0$ for subsequent rounds, hence the friendship value for all excursions is $0$.

For the second test case, there is only one pair possible $(1, 2)$ and its friendship value is initially $1$, so each turn they are picked and their friendship value increases by $1$. Therefore, the total sum is $1+2+3+\ldots+10 = 55$.

For the third test case, the final answer is $\frac{7}{9} = 777\,777\,784\bmod (10^9+7)$.

 

解题思路

  纯数学题,看到期望题不要总想着用概率 dp 去做,可以尝试结合贡献法与最原始求期望的做法去思考。

  由于期望具有线性性,可以单独考虑每一对好友对期望的贡献是多少(因为非好友的 $f_i$ 始终为 $0$ 因此不用考虑)。对于第 $i$ 对好友的 $f_i$,由于 $k$ 次选择是相互独立的,因此有可能会被选择了 $0, \, 1, \, \ldots, \, k$ 次。由于每次被选择后 $f_i$ 都会加 $1$,因此每种情况贡献的期望是不同的,要分别计算。

  所以第 $i$ 对好友对期望的总贡献是 $\sum\limits_{j=0}^{k}{\left( f_i + f_i+1 + \cdots + f_i+j-1 \right) \cdot p_{i,j}}$,其中 $p_{i,j}$ 表示 $k$ 次选择中第 $i$ 对好友被选择了 $j$ 次概率。

  考虑如何求出 $p_{i,j}$。我们知道概率的本质是该事件出现的总次数除以所有可能发生的事件的总数,而所有可能发生的事件的总数很容易知道,因为 $k$ 次选择是相互独立的,每一次选择是从 $n$ 个人中任意选择两个组成一对,共 $C_{n}^{2}$ 种选法,根据乘法原理 $k$ 次选择一共会有 $\left( C_{n}^{2} \right)^k$ 种选法。那么在这 $k$ 次的选择中,其中有 $j$ 次是第 $i$ 对好友的选法有多少种?先从 $k$ 次选择中选出 $j$ 个表示第 $i$ 对好友,有 $C_{k}^{j}$ 种选法,那么剩下的 $k-j$ 个只能选其他的数对,有 $\left( C_{n}^{2} - 1 \right)^{k-j}$ 种选法。根据乘法原理一共就有 $C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}$ 种选法,因此 $p_{i,j}$ 就等于:$$p_{i,j} = \frac{C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}{\left( C_{n}^{2} \right)^k}$$

  因此第 $i$ 对好友对期望的总贡献就是:

$$\begin{align*}
&\sum\limits_{j=0}^{k}{\left( f_i + f_i+1 + \cdots + f_i+j-1 \right) \cdot \frac{C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}{\left( C_{n}^{2} \right)^k}} \\
=& \frac{1}{\left( C_{n}^{2} \right)^k} \cdot \sum\limits_{j=0}^{k}{\left( f_i + f_i+1 + \cdots + f_i+j-1 \right) \cdot C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}
\end{align*}$$

  因此 $m$ 对好友对期望的贡献就是:$$\frac{1}{\left( C_{n}^{2} \right)^k} \cdot \sum\limits_{i=1}^{m}{\sum\limits_{j=0}^{k}{\left( f_i + f_i+1 + \cdots + f_i+j-1 \right) \cdot C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}}$$

  如果直接按公式算的话那么时间复杂度至少为 $O(m \cdot k)$,可以发现对于每个 $j$,$\left( C_{n}^{2} - 1 \right)^{k-j}$ 这部分都是一样的,只有 $\left( f_i + \cdots + f_i+j-1 \right)$ 不同,并且随着 $j$ 的增加,每次都会增加一项 $f_i+j-1$,这启发我们可以动态维护这部分的和从而避免枚举 $i$。具体做法是初始设 $\text{sum} = 0$,枚举到 $j$ 时令 $\text{sum} \gets \text{sum} + s + m \cdot (j-1)$,其中 $s = \sum\limits_{i=1}^{m}{f_i}$。

  AC 代码如下,时间复杂度为 $O\left(n \cdot\left( \log{k} + \log{\text{mod}} \right) \right)$:

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

typedef long long LL;

const int mod = 1e9 + 7;

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, m, k;
    scanf("%d %d %d", &n, &m, &k);
    int s = 0;
    for (int i = 0; i < m; i++) {
        int x;
        scanf("%*d %*d %d", &x);
        s = (s + x) % mod;
    }
    int ret = 0, p = n * (n - 1ll) % mod * qmi(2, mod - 2) % mod;    // p=C(n,2)
    for (int i = 1, t = 1, sum = 0; i <= k; i++) {    // t是动态维护组合数C(k,j)
        t = t * (k - i + 1ll) % mod * qmi(i, mod - 2) % mod;
        sum = (sum + s + m * (i - 1ll)) % mod;
        ret = (ret + 1ll * sum * t % mod * qmi(p - 1 + mod, k - i)) % mod;
    }
    printf("%d\n", 1ll * ret * qmi(qmi(p, k), mod - 2) % mod);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

  再给出官方的做法,也是贡献法求期望,不过分成了两步,即分别求不变和变化两部分的期望。先求 $f_i$ 固定不变的情况,即无论第 $i$ 对好友被选择多少次 $f_i$ 都不会加 $1$,与上面的推导一样这部分对期望的贡献为 $f_i \cdot \sum\limits_{j=0}^{k}{j \cdot \frac{C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}{\left( C_{n}^{2} \right)^k}}$,化简一下就会变对成二项分布求期望的公式:

$$\begin{align*}
& f_i \cdot \sum\limits_{j=0}^{k}{j \cdot \frac{C_{k}^{j} \cdot \left( C_{n}^{2} - 1 \right)^{k-j}}{\left( C_{n}^{2} \right)^k}} \\
=& f_i \cdot \sum\limits_{j=0}^{k}{j \cdot C_{k}^{j} \cdot \frac{\left( C_{n}^{2} - 1 \right)^{k-j}}{\left( C_{n}^{2} \right)^{j} \cdot \left( C_{n}^{2} \right)^{k-j}}} \\
=& f_i \cdot \sum\limits_{j=0}^{k}{j \cdot C_{k}^{j} \cdot \left( \frac{1}{C_{n}^{2}} \right)^{j} \cdot \left( 1 - \frac{1}{C_{n}^{2}} \right)^{k-j}}
\end{align*}$$

  其中 $\frac{1}{C_{n}^{2}}$ 是在一次选择中选到第 $i$ 对好友的概率。

  根据二项分布的期望公式,若 $X \sim B(n,p)$,则 $E(X)=np$,因此第 $i$ 对好友这部分对期望的贡献就是 $\frac{k}{C_{n}^{2}} \cdot f_i$。因此不变的部分中,$m$ 对好友的贡献就是 $\frac{k}{C_{n}^{2}} \sum\limits_{i=1}^{m}{f_i}$。

  对于变化的部分,$m$ 对好友都是一样的,因此只需求一次,最后乘上 $m$ 即可。对于变化的部分就不再考虑 $f_i$ 了,而是统计增加的数值的期望,即如果 $k$ 次选择中某对朋友被选了 $j$ 次,那么增加的数值就是 $0 + 1 + \cdots + j-1 = \frac{j(j-1)}{2}$,因此变化部分的期望就是:$$m \cdot \sum\limits_{j=0}^{k}{\frac{j(j-1)}{2} \cdot C_{k}^{j} \cdot \left( \frac{1}{C_{n}^{2}} \right)^{j} \cdot \left( 1 - \frac{1}{C_{n}^{2}} \right)^{k-j}}$$

  因此总的期望就是:$$\frac{k}{C_{n}^{2}} \sum\limits_{i=1}^{m}{f_i} + m \cdot \sum\limits_{j=0}^{k}{\frac{j(j-1)}{2} \cdot C_{k}^{j} \cdot \left( \frac{1}{C_{n}^{2}} \right)^{j} \cdot \left( 1 - \frac{1}{C_{n}^{2}} \right)^{k-j}}$$

  AC 代码如下,时间复杂度为 $O\left(n \cdot\left( \log{k} + \log{\text{mod}} \right) \right)$:

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

typedef long long LL;

const int mod = 1e9 + 7;

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, m, k;
    scanf("%d %d %d", &n, &m, &k);
    int s = 0;
    for (int i = 0; i < m; i++) {
        int x;
        scanf("%*d %*d %d", &x);
        s = (s + x) % mod;
    }
    int ret = 0, p = 2ll * qmi(n * (n - 1ll) % mod, mod - 2) % mod;
    for (int i = 1, t = 1; i <= k; i++) {
        t = t * (k - i + 1ll) % mod * qmi(i, mod - 2) % mod;
        ret = (ret + i * (i - 1ll) % mod * t % mod * qmi(p, i) % mod * qmi(1 - p + mod, k - i)) % mod;
    }
    ret = (1ll * ret * m % mod * qmi(2, mod - 2) + 1ll * k * s % mod * p) % mod;
    printf("%d\n", ret);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 921 (Div. 1, Div. 2) Editorial:https://codeforces.com/blog/entry/125137

  Codeforces Round 921 (Div. 2) A-D:https://zhuanlan.zhihu.com/p/680178758

  Codeforces Round 921 (Div. 2) A - D讲解:https://www.bilibili.com/video/BV1ep4y1m7rJ/

标签:Good,frac,cdot,sum,int,right,Trip,left
From: https://www.cnblogs.com/onlyblues/p/18004740

相关文章

  • 数学概率拆分——cf_921_D.Good Trip
    目录问题概述思路想法参考代码问题反思问题概述原题参考:D.GoodTrip大致意思就是一个老师带着n个孩子,其中有m对是朋友,每对朋友之间有一个友谊值,不是朋友的则是0,这个老师要出去玩k次,每次可以带上两个小朋友(为什么不能一起带,这是偏爱!!!),如果这两个小朋友是朋友关系的话,那么他们的......
  • CF921 D. Good Trip
    题面代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineIOSios::sync_with_stdio(0);cin.tie(0);cout.tie(0);#definerep(i,a,n)for(inti=a;i<=n;i++)#defineper(i,a,n)for(inti=n;i>=a;i--)#definefirstfi#defineseconfse#defi......
  • Striped64源码阅读
    目录简介模型代码分析成员变量方法补充ThreadLocalRandomContended注解-解决伪共享问题参考链接本人的源码阅读主要聚焦于类的使用场景,一般只在java层面进行分析,没有深入到一些native方法的实现。并且由于知识储备不完整,很可能出现疏漏甚至是谬误,欢迎指出共同学习本文基于cor......
  • 【容斥反演】Nanami and Trip Schemes Count Problem
    链接给定\(k\)个特殊格子,求从(1,1)往右或往上走到(n,m),在经过不超过\(p\)个特殊格的情况下的方案数设\(f(S)\)表示钦定走S集合中格子的方案,\(g(S)\)为恰好走S集合的方案,那么\(f\)与\(g\)的关系就是一个\(\subseteq\)意义下的前缀和。即\[f(S)=\sum_{S\subs......
  • CF1925D Good Trip 题解
    考虑分别计算\(p\)和\(q\)。按照期望的定义,\(q\)应该等于方案的总数,也就是\(s^k\),其中\(s\)表示一共有多少个不同的组。考虑如何求\(p\),我们先只计算第\(i\)组对\(p\)的贡献。如果第\(i\)组一共被选了\(1\)次,那么贡献为:\[g=f_i\timesC_{k}^{1}\times(s-1)^{......
  • 初中英语优秀范文100篇-072Growing up with good books-伴随着好书成长
    PDF格式公众号回复关键字:SHCZFW072记忆树1Asthesayinggoes:“Knowledgeispower."翻译俗话说:“知识就是力量。”简化记忆知识句子结构As引导的短语,表示“正如……所说”,用于引用格言或谚语Knowledge作主语,是抽象名词。Is是系动词。Power作表语,是名词2We......
  • Goodbye2023
    GoodBye2023A2023题目描述给定n个数,让我们判断是否能与m个数相乘后可以得到2023,并且将这些数输出出来解题思路我们只需要判断这些数能否被2023整除。代码#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'#definefix(n)std::fixed<<std::......
  • QOJ7206 Triple
    QOJ传送门大分讨恶心题。首先施容斥,变成求\(\sum|AB|>\max(|AC|,|BC|)\)。遇到这种三个点的路径问题,可以找出一个点\(X\),使得\(A,B,C\)在\(X\)的不同子树内,也就是\(A\toB,A\toC,B\toC\)的路径的唯一一个交点\(X\)。那么:\[[|AB|>\max(|AC|,|BC|)]=......
  • [ARC155C] Even Sum Triplet 题解
    一道大分类讨论。如果有一个可以交换的段包含奇数,那么你可以把所有奇数移到最左边并任意调整相对顺序,然后回到任意一种有一个可以交换的段包含奇数的状态。这种情况,如果偶数的数量为\(2\),这两个偶数是不能交换相对位置的,有至少\(3\)个偶数就能交换偶数间相对位置。所以只需要......
  • 【Leetcode1949. 坚定的友谊】使用MySQL在无向图中寻找{"CompleteTripartite", {1, 1,
    目录题目地址思路代码MySQL代码逐行翻译为Pandas代码等效Cypher查询(未验证)题目地址https://leetcode.cn/problems/strong-friendship/思路就是在无向图中寻找这个pattern:(*Mathematica*)GraphData[{"CompleteTripartite",{1,1,3}}]SQL写还是比较麻烦。更加复杂的查询还是......