[Jzoj] 3055.比赛

题目大意

有两个队伍 A A A B B B,每个队伍都有 n n n个人。

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

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

A A A的得分减 B B B的得分的期望值。

题目解析

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

A A A队某人 X X X的期望得分为
在这里插入图片描述
(其中 y y y B B B队中实力低于 X X X的人, P P P代表 X X X Y Y Y相遇的概率)。

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

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

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

代码

#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、付费专栏及课程。

余额充值