[Jzoj] 3055.比赛

本文解析了一个关于两支队伍比赛得分期望值的算法问题。通过分析每个选手的实力值,利用数学期望的性质,提出了一个高效的算法解决方案。该算法首先对两队选手实力进行排序,然后通过维护实力值的前缀和,计算出每个选手对最终得分期望值的贡献。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

有两个队伍AAABBB,每个队伍都有nnn个人。

这两支队伍之间进行nnn111111比赛,每一场都是由AAA中的一个选手与BBB中的一个选手对抗。同一个人不会参加多场比赛,每个人的对手都是随机而等概率的。

每个选手都有一个非负的实力值。如果实力值为XXXYYY的选手对抗,那么实力值较强的选手所在的队伍将会获得(X−Y)2(X-Y)^2(XY)2的得分。

AAA的得分减BBB的得分的期望值。

题目解析

根据期望的和===和的期望,只需把AAA队每个人的期望得分减去BBB队每个人的期望得分即为答案。

AAA队某人XXX的期望得分为
在这里插入图片描述
(其中yyyBBB队中实力低于XXX的人,PPP代表XXXYYY相遇的概率)。

显然任意两个人相遇的概率是相等的,===两人第一场相遇的概率+++两人第一场不相遇的概率∗*两人第二场相遇的概率+++……。

排序后只需枚举一个人iii,用一个指针指着另一 队中实力比iii弱的里面最强的人,维护实力值的前缀和,实力值平方的前缀和即可算出期望。

显然指针只可能向右移动,所以这一步是线性的。

代码

#include<bits/stdc++.h>
#define L long long
using namespace std;
L n,l,r,t,ans,z,y;
L a[50005],b[50005],q1[50005],q2[50005];
double s,x=1;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) x*=i;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	for(int i=1;i<=n;i++)
	 q1[i]=q1[i-1]+b[i],q2[i]=q2[i-1]+(b[i]*b[i]);
	for(int i=1;i<=n;i++)
	{
	  while(a[i]>b[t]&&t<=n)
	   t++;
	  z=(t-1)*a[i]*a[i]+q2[t-1]-2*a[i]*q1[t-1];
	  y=(n-t+1)*a[i]*a[i]+q2[n]-q2[t-1]-2*a[i]*(q1[n]-q1[t-1]);
	  ans+=z-y;
	}
	s=ans;
	cout<<fixed<<setprecision(1)<<s/n;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值