hdu3282 Running Median(树状数组+二分)

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;
}
发布了364 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/103337311