Problem Description
For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by an odd decimal integer M, (1 ≤ M ≤ 9999), giving the total number of signed integers to be processed.
The remaining line(s) in the dataset consists of the values, 10 per line, separated by a single space.
The last line in the dataset may contain less than 10 values.
Output
For each data set the first line of output contains the data set number, a single space and the number of medians output (which should be one-half the number of input values plus one). The output medians will be on the following lines, 10 per line separated by a single space. The last line may have less than 10 elements, but at least 1 element. There should be no blank lines in the output.
Sample Input
3
1 9
1 2 3 4 5 6 7 8 9
2 9
9 8 7 6 5 4 3 2 1
3 23
23 41 13 22 -3 24 -31 -11 -8 -7
3 5 103 211 -311 -45 -67 -73 -81 -99
-33 24 56
Sample Output
1 5
1 2 3 4 5
2 5
9 8 7 6 5
3 12
23 23 22 22 13 3 5 5 3 -3
-7 -3
题意:
输入n个数,每奇数个数的时候输出一次中位数。
思路:
求前x个数的中位数用树状数组+二分
因为用的是树状数组的桶,而输入的数据中有负数,所以还需要离散化
ps:
这题的输出格式好坑,pe好多次
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e4+5;
int a[maxm];
int xx[maxm];
int c[maxm];
int lowbit(int i){
return i&-i;
}
void add(int i){
while(i<maxm){
c[i]++;
i+=lowbit(i);
}
}
int ask(int i){
int ans=0;
while(i){
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
signed main(){
int T;
cin>>T;
while(T--){
int cas;
cin>>cas;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
xx[i]=a[i];
}
sort(xx+1,xx+1+n);
int num=unique(xx+1,xx+1+n)-xx-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(xx+1,xx+1+num,a[i])-xx;
}
memset(c,0,sizeof c);//清空树状数组
vector<int>res;
int ma=0;
for(int i=1;i<=n;i++){
add(a[i]);
ma=max(ma,a[i]);
if(i&1){//如果是奇数需要输出中位数
int l=1,r=ma;
int ans=0;
while(l<=r){//二分枚举离散化之后的中位数
int mid=(l+r)/2;
if(ask(mid)>=i/2+1){
ans=mid;
r=mid-1;
}else{
l=mid+1;
}
}
res.push_back(xx[ans]);
}
}
int len=(n+1)/2;
cout<<cas<<' '<<len<<endl;
for(int i=0;i<len;i++){
cout<<res[i];
if((i+1)%10==0||i==len-1)cout<<endl;//满10个换行 或 最后一个数换行
else cout<<' ';
}
}
return 0;
}