题目大意
有两个队伍 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 (X−Y)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;
}