首页 > 其他分享 >ABC 314 F 题解

ABC 314 F 题解

时间:2023-08-13 10:11:55浏览次数:123  
标签:得分 ABC 期望 比赛 int 题解 314 队伍 siz

原题传送门


题意

有 n 支队伍进行比赛,起初,第 i 支队伍只有选手 i 一个人。总共要进行 n-1 场比赛,每次给出 p 和 q,意为让 p 所在的队伍与 q 所在的队伍进行比赛(数据保证此时 p 和 q 不在同一支队伍),设 p 所在的队伍有 \(siz_p\) 个人,q 所在的队伍有 \(siz_q\) 个人,则此次比赛中 p 所在队伍获胜的概率为 \(\frac{siz_p}{siz_p+siz_q}\),q 所在队伍获胜的概率为 \(\frac{siz_q}{siz_p+siz_q}\)。获胜队伍的所有成员都可以获得一分,并且此次比赛结束后会将这两支队伍合并为一支队伍。对于这 n 个人,求出每个人的得分期望。


大致思路

如果我们暴力地计算答案,也就是每次比赛都给两队中的人一个一个地去加上本次得分的期望,那么时间复杂度会达到 \(O(n^2)\),无法通过此题,考虑优化。我们考虑为什么这个暴力算法会很慢,也就是考虑它有哪些计算是可以省去或者暂时省去(最后再统一计算)的。那么我们假设有一场队伍 i 和队伍 j 的比赛 p,比赛结束后合并为队伍 k,那么其实队伍 k 之后的所有得分期望对于 i 和 j 中的成员都是有效的,所以我们其实可以利用一种类似前缀的东西,我们把队伍 k 产生之后的所有得分期望统计起来,最后再分别加上 i 和 j 两支队伍再比赛 p 中的得分期望就可以统计出答案。这样就可以不需要把队伍 k 产生之后的每次比赛的得分期望都去给 i 和 j 中的成员一个一个地加上。


代码实现

我们把每一次两支队伍之间的比赛视作两个个体之间的二元关系,再结合上文所说的类似前缀的东西,可以发现可以很完美地体现出这两个性质:将二元关系转化为树边,将类似前缀的东西转化为树上的父亲和儿子之间的递进关系。

我们再考虑如何合并两支队伍,合并时我们将两支队伍视作两棵树,用一个新的节点作为新的根把这两棵树合并起来,比如我们要合并队伍 i 和队伍 j,就建立一个新的节点 k,然后从 k 连两条边分别指向 i 和 j,并且权值分别为此次比赛中队伍 i 和队伍 j 的得分期望。

然后因为题目中说每次会给出两个选手的编号,所以我们还需要每次快速判断选手所在的队伍,这个可以用并查集 \(O(n)\) 实现。

最后统计答案的时候 dfs一遍记录边权的前缀就可以完成了。

时间复杂度为 \(O(n)\)。

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define int long long
const int N=400200,mod=998244353;
int n,p[N],q[N],idx;
int ans[N],fa[N],siz[N];
int idx_e,head[N],inv[N];
inline int read(){
    re int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
struct edge{
	int u,v,w,nxt;
}e[N];
il void adde(int u,int v,int w){
	e[++idx_e]={u,v,w,head[u]};
	head[u]=idx_e;
}
il void init(){
	inv[1]=1;
	for(re int i=2;i<=n;i++)inv[i]=inv[mod%i]*(mod-mod/i)%mod;//预处理逆元 
	for(re int i=1;i<=n;i++)fa[i]=i,siz[i]=1;//并查集初始化 
	for(re int i=n+1;i<=(n<<1);i++)fa[i]=i;
	//注意这里我们额外建立的节点是没有人的 
}
il int fnd(int x){
	if(fa[x]==x)return x;
	return fa[x]=fnd(fa[x]);
}
il void merge(int x,int y){
	x=fnd(x),y=fnd(y);//找到所在队伍 
	idx++;//建立新的节点 
	fa[x]=idx,fa[y]=idx;
	siz[idx]=siz[x]+siz[y]; 
	int kop=inv[siz[idx]];
	adde(idx,x,siz[x]*kop%mod),adde(idx,y,siz[y]*kop%mod);
	//计算期望并建边 
}
il void dfs(int x,int sum){
	if(x<=n)ans[x]=sum;
	//如果 <=n 说明是选手而非我们额外建立的节点,那么就记录答案 
	for(re int i=head[x];i;i=e[i].nxt){
		int v=e[i].v;
		sum=(sum+e[i].w)%mod;//记录前缀 sum 
		dfs(v,sum);
		sum=(sum+mod-e[i].w)%mod;
	}
}
signed main(){
	n=read();
	init();
	idx=n;
	//为了避免和之前的节点编号重复,我们把新的节点从 n+1 开始编号 
	for(re int i=1;i<n;i++){
		int p=read(),q=read();
		merge(p,q);//进行比赛 
	}
	dfs(idx,0);
	for(re int i=1;i<=n;i++)cout<<ans[i]<<' ';
    return 0;
}

标签:得分,ABC,期望,比赛,int,题解,314,队伍,siz
From: https://www.cnblogs.com/MrcFrst-LRY/p/17626201.html

相关文章

  • 【KMP】border 题解
    题目描述输入输出样例输入abaabaa样例输出17样例解释:f[2][a]=1f[3][a]=1f[4][a]=1f[4][b]=2f[5][a]=1f[5][b]=2f[6][a]=3f[7][a]=4f[7][b]=2以上为>0的f[][],求和=17数据范围限制这一篇同上一篇,都是从以前博客搬过来的,所以真的是......
  • 猴子拆房 题解
    题目描述输入输出样例输入【样例输入1】22345【样例输入2】3242513【样例输入3】6353417174241样例输出【样例输出1】3【样例输出2】0【样例输出3】10数据范围限制提示这个是我的,是我的QWQ,我没有转载,只是把以前的博客搬运......
  • 「题解注释」P7518 [省选联考 2021 A/B 卷] 宝石
    联合省选2021宝石题解-hezlik的博客-洛谷博客(luogu.com.cn)耗时:一晚上+半个上午代码注释:#include<bits/stdc++.h>usingnamespacestd;constintN=500000,C=21;intRi(){intx=0,y=1;charc=getchar();for(;c<'0'||c>'9';c=getchar())if......
  • CF452C 题解
    洛谷链接&CF链接题目简述有\(m\timesn\)张牌,有\(n\)个种类,每个种类有\(m\)张,现在抽一张放回,再抽一张,求这张牌与第一张抽出的牌种类相同的概率。思路本题是一道结论题,我们来推一下公式。首先需要特判一个点:只有\(1\)张牌,即\(n=m=1\),那么两次抽都会是这张牌,所......
  • ABC314
    T1:3.14模拟代码实现s='3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'n=int(input())ans=s[0:n+2]print(ans)T2:Roulette模拟代码实现#include<bits/stdc++.h>#definerep(i,n)for......
  • acwing 116.飞行员兄弟 (算法竞赛进阶指南 p48 t1 ) 题解
    原题链接https://www.acwing.com/problem/content/description/118/题目描述“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。已知每个把手可以处于以下两种状态之一:打开或关闭。只有当所有把手都打开时,冰箱才会打开。把手可以表示为一个4х4的矩阵,您可以......
  • IDEA/Android Studio的gradle控制台输出中文乱码问题解决
    原文地址:IDEA/AndroidStudio的gradle控制台输出中文乱码问题解决-Stars-One的杂货小窝在项目中,有使用到Gradle自定义脚本,会有些输出日志,但是输出中文就变成乱码了..本篇就介绍下解决方法乱码效果如下图所示步骤我是window系统,不知道其他系统会不会出现这个问题乱......
  • Codeforces Round 874 G题解
    做不动那么多题了,来个GG就是问你一棵树能切成多少个大小为3的链,想了半天,想过dp啥的,但是后来发现这个贪心就好了,可以证明贪心找不到的,其他方法也找不到好久没复健了,这是第一次,感觉以后要多做题才可以#include<bits/stdc++.h>usingnamespacestd;constexprintlimit=(4e......
  • 国标GB28181视频平台LntonGBS(源码版)国标视频云服务平台主子码流都为H.265时,切换出现花
    国标视频云服务LntonGBS平台是基于国标GB28181协议的平台,可实现的视频能力有:实时直播、视频录像、语音对讲、云存储、检索及回放、告警、级联等。平台支持将接入的视频流进行全终端、全平台分发,分发的视频流包括RTSP、RTMP、FLV、HLS、WebRTC等格式。最近有用户反馈,在LntonGBS平台......
  • RTSP流媒体服务器LntonNVR(源码版)安防监控平台开启录像后,录像回看无数据的问题解决方案
    LntonNVR平台通过RTSP/ONVIF协议实现了优秀的视频能力。它可以采集前端接入设备的音视频资源,并将其转码成适用于全平台、全终端分发的视频流格式,包括RTMP、FLV、HLS、WebRTC等格式。这使得LntonNVR平台具备了视频监控直播、云端录像、检索与回看、告警等安防监控功能。平台部署轻快......