Jzoj 3055NOIP2012模拟10.27期望比赛

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jzoj 3055NOIP2012模拟10.27期望比赛相关的知识,希望对你有一定的参考价值。

【NOIP2012模拟10.27】比赛

Link

Jzoj【3055】【NOIP2012模拟10.27】比赛


题面

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

对于30%的数据,n≤50。
对于100%的.据,n≤50000;A[i],B[i]≤50000。


解题思路

考场上已经打到正解了,结果概率处理写错了[怒][怒][怒]
以下先不说概率,最后再说

完全平方式都会拆吧,拆完之后 ∑ a 2 + b 2 − 2 a ⋅ b \\sum a^2+b^2-2a·b a2+b22ab,当然还有b比a大 ∑ − ( a 2 + b 2 + 2 a ⋅ b ) \\sum -(a^2+b^2+2a·b) a2+b2+2ab = ∑ − a 2 − b 2 + 2 a ⋅ b \\sum -a^2-b^2+2a·b a2b2+2ab

先算平方和,再算那什么2a·b
把a和b都丢到一个数组里排序,然后O(n)处理前面和后面
如果当前是a,前面有x个b比它小(产生分数为正),后面有y个b比它大(产生分数为负)
那么a的平方和为 a 2 ∗ x − a 2 ∗ y = a 2 ∗ ( x − y ) a ^ 2 * x - a ^ 2 * y= a ^ 2 * (x - y) a2xa2y=a2(xy)
b也一样

用两个变量累计前面的b的和,后面的b的和
那个2*balabala, 2 ∗ a ∗ q i a n − 2 ∗ a ∗ h o u = 2 ∗ a ( q i a n − h o u ) 2 * a * qian - 2 * a * hou = 2 * a(qian - hou) 2aqian2ahou=2a(qianhou)

然后全部加起来就好了

再说概率
每个分数乘上这两个数互打概率, n ! n = ( n − 1 ) ! \\frac{n!}{n}=(n - 1)! nn!=(n1)!
然后最后每种组合都要除以出现概率(多少种组合), a n s n ! \\frac{ans}{n!} n!ans
( n − 1 ) ! n ! \\frac{(n-1)!}{n!} n!(n1)!不就是 1 n \\frac{1}{n} n1了吗

只用在输出的时候用ans / n就好了


Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#define ll unsigned long long
#define ldb long double
#define N 501000

using namespace std;

struct DT{
	ldb s;
	int i, id;
	ldb q, h;
}c[2 * N];
ldb ans, chu;
int n;
ldb x, jian, jia, qian[N], hou[N];

bool cmp(const DT&k, const DT&l) {
	if(k.s == l.s) return k.i < l.i;
	return k.s < l.s;
}

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%Lf", &x);
		c[i] = (DT){x, i, 1, (ldb)1, (ldb)-1};
		  //q,h标记产生分数的正负;a和b是不一样的
	}
	for(int i = 1; i <= n; i ++) {
		scanf("%Lf", &x);
		jia += x;
		c[i + n] = (DT){x, i, 2, (ldb)-1, (ldb)1};
	}
	sort(c + 1, c + 1 + n * 2, cmp);
	for(int i = 1; i <= n * 2; i ++) {
		if(c[i].id != c[i - 1].id) //一个a一个b,假设当前是a,上一个是b
			qian[i] = (i - 1) - qian[i - 1];
			  //(i-1)是前面有多少个数,qian[i-1]就是前面有多少个a,减掉之后就是有多少个前面b
		else qian[i] = qian[i - 1];
	}
	for(int i = n * 2; i; i --) {
		if(c[i].id != c[i + 1].id)  //同上
			hou[i] = (n * 2 - i) - hou[i + 1];
		else hou[i] = hou[i + 1];
	}
	for(int i = 1; i <= n * 2; i ++) {
		if(c[i].id == 2)
			jian += c[i].s, jia -= c[i].s;  //更新前面、后面b的和
		else ans += (ldb)(2 * (ldb)c[i].s * (ldb)(jia - jian));  //加上2*a*b
		ans += (ldb)(c[i].s * c[i].s * (c[i].q * qian[i] + c[i].h * hou[i]));  //加上a^2或b^2
	}
	printf("%.1Lf", ans / n);  //除以n
}

以上是关于Jzoj 3055NOIP2012模拟10.27期望比赛的主要内容,如果未能解决你的问题,请参考以下文章

Jzoj 3056NOIP2012模拟10.27容斥DP数学数字

[jzoj]2938.NOIP2012模拟8.9分割田地

10.27 noip模拟试题(moring)

10.27 noip模拟试题(afternoon)(跪在游戏玩少了2333)

Jzoj4742NOIP2016提高A组模拟9.2快速幂单峰

jzoj4624NOIP2016A组模拟7.13KMP数学字符串匹配