CF913F Strongly Connected Tournament

题面

题解

设 \(f(n)\) 表示 \(n\) 个人比赛总场数的期望值,通过枚举拓补序最后的强连通分量可得:
\[
f(n) = \sum_{i = 1}^n s(i)c(n, i)\left[f(i) + f(n - i) + i(n - i) + \frac{i(i - 1)}2 \right]
\]
其中 \(s(n)\) 表示 \(n\) 个点能够形成强连通分量的概率,\(c(n, i)\) 表示 \(n\) 个点中有 \(i\) 个点被剩下 \(n - i\) 个点打败的概率。

这样就可以很好地理解后面那一堆东西:\(f(i)\) 和 \(f(n - i)\) 表示内部分别解决的场次,\(i(n - i)\) 是比出那 \(i\) 个最菜的人需要的场次,\(\dfrac {i(i-1)}2\) 是 \(i\) 个人形成强连通分量需要的场次。

由于 \(c(n, n) = 1\),所以上式中的 \(f(n)\) 可以解出来,为:
\[
f(n) = \frac 1{1 - s(n)}\left\{\sum_{i=1}^{n - 1} s(i)c(n - i)\left[f(i) + f(n - i) + i(n - i) + \frac {i(i - 1)}2 \right] \right\}
\]
接下来考虑如何求 \(c(n, i)\)。

边界条件 \(c(n, 0) = 1\),通过讨论 \(n\) 是否被吊打可以得出:
\[
c(n, i) = (1 - p)^ic(n - 1, i) + p^{n - i}c(n - 1, i - 1)
\]
\(s(n)\) 同样比较好求,同样枚举拓补序最后一个强连通分量得:
\[
s(n) = 1 - \sum_{i = 1}^{n - 1} s(i)c(n, i)
\]
于是问题解决,时间复杂度 \(\Theta(n^2)\)。

代码

#include <cstdio>
#include <algorithm>
#include <vector>

inline int read()
{
    int data = 0, w = 1; char ch = getchar();
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') w = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    return data * w;
}

const int N(2010), Mod(998244353);
int n, a, b, p[N], q[N], c[N][N], f[N], s[N];
inline int C(int x) { return 1ll * x * (x - 1) / 2 % Mod; }
int fastpow(int x, int y)
{
    int ans = 1;
    for (; y; y >>= 1, x = 1ll * x * x % Mod)
        if (y & 1) ans = 1ll * ans * x % Mod;
    return ans;
}

int main()
{
    p[0] = q[0] = 1;
    n = read(), a = read(), b = read(), a = 1ll * a * fastpow(b, Mod - 2) % Mod;
    for (int i = 1; i <= n; i++) p[i] = 1ll * p[i - 1] * a % Mod;
    a = Mod + 1 - a;
    for (int i = 1; i <= n; i++) q[i] = 1ll * q[i - 1] * a % Mod;
    for (int i = 0; i <= n; i++) c[i][0] = 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j++)
            c[i][j] = (1ll * q[j] * c[i - 1][j] + 1ll * p[i - j] * c[i - 1][j - 1]) % Mod;
    for (int i = 1; i <= n; i++) s[i] = 1;
    for (int i = 2; i <= n; i++) for (int j = 1; j < i; j++)
        s[i] = (s[i] - 1ll * s[j] * c[i][j] % Mod + Mod) % Mod;
    for (int i = 2; i <= n; i++)
    {
        f[i] = 1ll * s[i] * C(i) % Mod;
        for (int j = 1; j < i; j++)
            f[i] = (f[i] + 1ll * s[j] * c[i][j] % Mod * ((f[j] + f[i - j]) % Mod + (1ll * j * (i - j) % Mod + C(j)) % Mod) % Mod) % Mod;
        f[i] = 1ll * f[i] * fastpow(Mod + 1 - s[i], Mod - 2) % Mod;
    }
    printf("%d\n", f[n]);
    return 0;
}

原文地址:https://www.cnblogs.com/cj-xxz/p/12189690.html

时间: 2024-10-05 05:04:55

CF913F Strongly Connected Tournament的相关文章

【CF913F】Strongly Connected Tournament 概率神题

[CF913F]Strongly Connected Tournament 题意:有n个人进行如下锦标赛: 1.所有人都和所有其他的人进行一场比赛,其中标号为i的人打赢标号为j的人(i<j)的概率为$p=a\over b$.2.经过过程1后我们相当于得到了一张竞赛图,将图中所有强联通分量缩到一起,可以得到一个链,然后对每个大小>1的强联通分量重复过程1.3.当没有大小>1的强连通分量时锦标赛结束. 现在给出n,a,b,求期望比赛的场数. $n\le 2000,a<b\le 1000

【CodeForces】913 F. Strongly Connected Tournament

[题目]F. Strongly Connected Tournament [题意]给定n个点(游戏者),每轮游戏进行下列操作: 1.对于游戏者i和j(i<j),有p的概率i赢j(反之j赢i),连边从赢者向输者,从而得到一个有向完全图,这些点视为进行了一轮游戏. 2.对于其中点数>1的强连通分量再次进行过程1,直至不存在点数>1的强连通分量为止. 给定n和p,求所有点进行的游戏轮数之和,2<=n<=2000. [算法]数学概率,期望DP [题解]参考:官方题解Hello 201

CodeforcesF. Strongly Connected Tournament

n<=2000个人参加比赛,这样比:(这里的序号没按题目的)1.两两比一场,比完连个图,边i->j表示i赢了j.2.连完那个图强联通分量缩起来,强连通分量内继续比,即强连通分量递归进行1.2,直到每个强连通分量大小为1.i<j时i有a/b的概率赢j,问每个人比赛的场数的总和的期望,答案%998244353. n个人搞完一次会有大大小小的联通块,就可以递归下去了!但是每次可能分出很多种情况,怎么算呢?选他的一个每种图一定有的强连通分量来枚举即可,那就枚举拓扑序最后的那一个分量,也就是输给了

@codeforces - [email&#160;protected] Strongly Connected Tournament

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] n 个选手参加了一场竞赛,这场竞赛的规则如下: 1.一开始,所有选手两两之间独立进行比赛(没有平局). 2.主办方将胜者向败者连边形成 n 个点的竞赛图. 3.主办方对这个竞赛图进行强连通分量缩点. 4.每一个强连通分量内部的选手重复步骤 1~3,直到每一个强连通分量内只剩一个选手.

PTA Strongly Connected Components

Write a program to find the strongly connected components in a digraph. Format of functions: void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ); where Graph is defined as the following: typedef struct VNode *PtrToVNode; struct VNode

HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】

Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4635 Description Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can

HDU 4635 Strongly connected (有向图的强连通分量)

Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the grap

[tarjan] hdu 4635 Strongly connected

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1568    Accepted Submission(s): 654 Problem Description Give a simple dir

HDU 4635 Strongly connected(强连通)经典

Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1828    Accepted Submission(s): 752 Problem Description Give a simple directed graph with N nodes and M edges. Please tell me