Description
有两个队伍A和B,每个队伍都有n个人。这两支队伍之间进行n场1对1比赛,每一场都是由A中的一个选手与B中的一个选手对抗。同一个人不会参加多场比赛,每个人的对手都是随机而等概率的。例如A队有A1和A2两个人,B队有B1和B2两个人,那么(A1 vs B1,A2 vs B2)和(A1 vs B2,A2 vs B1)的概率都是均等的50%。
每个选手都有一个非负的实力值。如果实力值为X和Y的选手对抗,那么实力值较强的选手所在的队伍将会获得(X-Y)^2的得分。
求A的得分减B的得分的期望值。
Input
第一行一个数n表示两队的人数为n。
第二行n个数,第i个数A[i]表示队伍A的第i个人的实力值。
第三行n个数,第i个数B[i]表示队伍B的第i个人的实力值。
Output
输出仅包含一个实数表示A期望赢B多少分。答案保留到小数点后一位(注意精度)。
Sample Input
2
3 7
1 5
Sample Output
20.0
Data Constraint
Hint
对于30%的数据,n≤50。
对于100%的.据,n≤50000;A[i],B[i]≤50000。
分析:这题我居然比赛时就AC了!!!(不可思议)。我们假设A队不变,B队有可能是全排列的任何一种,每种的概率为n!。然后,我们看到每一种全排列,每个人都有可能要pk另一队的任意一人,而在全排列中,每个人pk另一个人的不止只是一次,而是(n-1)!次。然后我们就可以求解了。
设A队实力为A[i],B队实力为B[i],则
ans=ans+(a[i]-b[j])^2 (1<=i<=n,1<=j<=n)
我们可以用完全平方公式化简,得
ans=ans+a[i]^2+b[j]^2+2*a[i]*b[j];
可以先求一次B[i]的前缀和和平方前缀和,不过b[i]>a[i] 时,答案要是负数,所以我们排序,二分求出第一个比A[i]大的数即可求解。
代码:
var
n,i,t,he:longint;
sum,sqrsum:array [0..50001] of extended;
ans,x,y,s,s1:extended;
a,b:array [0..50001] of longint;
procedure qsort(l,r:longint);
var
i,j,key,temp:longint;
begin
if l>=r then exit;
i:=l;j:=r;
key:=b[l+random(r-l+1)];
repeat
while (b[i]<key) do inc(i);
while (b[j]>key) do dec(j);
if i<=j then
begin
temp:=b[i];b[i]:=b[j];b[j]:=temp;
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
function find(x:longint):longint;
var l,r,mid:longint;
begin
l:=0; r:=n+1;
while l<=r do
begin
mid:=(l+r) shr 1;
if x=b[mid] then exit(mid);
if r-l<=1 then break;
if x<b[mid] then r:=mid
else l:=mid;
end;
exit(l);
end;
begin
readln(n);
s:=n;
for i:=1 to n do
read(a[i]);
for i:=1 to n do
read(b[i]);
qsort(1,n);
b[0]:=-maxlongint; b[n+1]:=maxlongint;
for i:=1 to n do
begin
s1:=(b[i]/s)*b[i];
sqrsum[i]:=sqrsum[i-1]+s1;
sum[i]:=sum[i-1]+b[i];
end;
for i:=1 to n do
begin
he:=find(a[i]);
x:=sqrsum[he]+(a[i]/s)*a[i]*he-2*sum[he]*(a[i]/s);
y:=(sqrsum[n]-sqrsum[he])+(a[i]/s)*a[i]*(n-he)-2*(sum[n]-sum[he])*(a[i]/s);
ans:=ans+x-y;
end;
writeln(ans:0:1);
end.