您的位置:首页 > 其它

16.9.5 C组第二题:3055

2016-09-05 20:01 411 查看
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。

思路:题目要求的是:



其中正负由a[i]和b[i]的大小关系决定分值的正负

正负的处理可以对b排序,比a[i]大的取负,比a[i]小的取正

上面的式子展开之后可以得到:



对于每个a[i]可以预处理b的前缀和与前缀平方和

这些思路想起来并不是很困难,最重要的就是精度问题,某人被卡44次,我表示呵呵哒,再次赐予一个滑稽给他,希望他能有智慧!


在此提示:c++被卡精度可以用0.1Lf的格式,注意F要大写,同时也可以用printf(“%0.1lf\n”,(double)ans);

代码如下:(不完整,只有一部分,请自己思考吧!)

#include<cstdio>
#include<algorithm>
#define F(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int maxn = 50000 + 500;
long long n,sum[maxn],a[maxn],b[maxn];
long double q[maxn];
long double m,ans=0.0;
long double sqr(long double x){return x*x;}
int main()
{
freopen("2.in","r",stdin);

scanf("%lld",&n);

m=n*1.0;

sum[0]=0;
q[0]=0;

F(i,1,n)
scanf("%lld",&a[i]);

F(i,1,n)
scanf("%lld",&b[i]);

sort(a+1,a+n+1);
sort(b+1,b+n+1);

F(i,1,n)
{
sum[i] = sum[i-1] + (double)b[i],
q[i]= q[i-1] + (double) ?(b[i]);
}
int x=0;
F(i,1,n)
{
while (x<n && a[]>b[]) x++;
ans += (double)(x * sqr(a[i]) + q[x]- 2 * a[i] * sum[x]) / ?;
ans -= (double)((n - x) * sqr(a[i]) + q
- q[x] - 2 * a[i] * (sum
- sum[x])) / ?;
}
printf("%0.1f\n",(double)ans);
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tj 前缀和