Weighted Median
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Description
For n elements x1, x2, ..., xn with positive integer weights w1, w2, ..., wn. The weighted median is the element xk satisfying
and
, S indicates



Can you compute the weighted median in O(n) worst-case?
Input
There are several test cases. For each case, the first line contains one integer n(1 ≤ n ≤ 10^7) — the number of elements in the sequence. The following line contains n integer numbers xi (0 ≤ xi ≤ 10^9). The last line contains n integer numbers wi (0 < wi < 10^9).
Output
One line for each case, print a single integer number— the weighted median of the sequence.
Sample Input
7 10 35 5 10 15 5 20 10 35 5 10 15 5 20
Sample Output
20
Hint
The S which indicates the sum of all weights may be exceed a 32-bit integer. If S is 5,
equals 2.5.

给出一个数列,对于数列中的每一个数都有对应的权值,将所有的权值加起来除以2.求以哪个数为界可满足题目要求。
解题思路:先按从小到大的顺序排序,当Xk为第一个数时,小于Xk的和最小,大于Xk的和最大。当Xk逐渐向右移时,小于Xk的和逐渐变大,大于Xk的和逐渐变小。也就是说,越向右移动,越能满足
这个条件。再看
这一侧,虽然变得越来越大,会面临突破S/2的一刻,但突破之前一直是满足题目条件的。


所以说,在突破的那一刻,该数的右侧所有数的和,为尽可能的小,该数左侧所有数的和,满足题目所给条件,即该点为Xk。
某一个数将一个数列分成两块,随着前面的变化,后面也会有规律的变化。
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct number{
int number;
int weight;
}stu[10000009];
bool cmp(struct number a,struct number b)
{
if(a.number==b.number)
return a.weight<b.weight;
return a.number<b.number;
}
int main()
{
int i,t;
long long int y,ab;
double mid;
while(scanf("%d",&t)!=EOF)
{
y=0;
ab=0;
for(i=0;i<=t-1;i++)
scanf("%d",&stu[i].number);
for(i=0;i<=t-1;i++)
{
scanf("%d",&stu[i].weight);
y+=stu[i].weight;
}
mid=y/2.0;
sort(stu,stu+t,cmp);
for(i=0;i<=t-1;i++)
{
ab+=stu[i].weight;
if(ab>=mid)
{
printf("%d\n",stu[i].number);
break;
}
}
}
return 0;
}