[TOJ 3515][优先队列]Middle number

题目描述
题目来源: TOJ 3515 (原题面为英文)
有一个整数序列,我们现在有两个操作:
1.add a:意味着在序列的结尾添加一个整数 a ,形成一个长度为 n+1 的序列。
2.mid:输出当前序列的中位数。
所谓中位数,就是这个序列按升序排列后中间位置的数(如果序列的长度是偶数,那么中位数就是此序列中间两个数中较小的)
示例1:序列为 1 2 13 14 15 16,则中位数为 13。
示例2:序列为 1 3 5 7 10 11 17,则中位数为 7 。
示例3:序列为 1 1 1 2 3,则中位数为 1 。
输入格式:
第一行输入一个整数 T(T≤10) ,表示测试数据的组数。
对每组数据:
第一行是一个整数 N(1≤N≤100000),表示序列长度;
接下来一行是 N 个整数,表示这个序列;
接下来一行是一个整数 M(0≤M≤10000),表示有M个操作;
接下来有 M 行,每行是由 add 或 mid 开头表示一个操作。
输出格式:
对于每组的每个 mid 操作,输出此时序列中符合题意的中位数。
样例输入:

1
6
1 2 13 14 15 16
5
add 5
add 3
mid
add 20
mid

样例输出:

5
13

PS:此中文题面来源soj之zgs。
题目分析
不难。我们可以将原序列升序排序后分成两个堆,大根堆和小根堆(优先队列实现,q1,q2),q1(大根堆)存较小的部分,q2(小根堆)存较大的部分(即q2中的元素均大于q1中的元素)。使q1中的个数大于等于q2中的个数(相等或多1),这样中位数就是q1的堆顶。每次修改操作,读入x,如果加入前的个数是奇数(必然应q1个数不变,q2个数+1),则取出q1的堆顶,与x比较,较大的加入q2,较小的加入q1。个数是偶数,(必然应q1个数+1,q2个数不变),则取出q2的堆顶,然后操作同上。
附代码

#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;

const int N=1e5+10;
int t,n,ans,m,a[N],tot,x,y;
char s[10];

int readint()
{
    char ch;int i=0,f=1;
    for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    if(ch=='-') {ch=getchar();f=-1;}
    for(;ch>='0'&&ch<='9';ch=getchar()) i=(i<<3)+(i<<1)+ch-'0';
    return i*f;
}

int main()
{
    //freopen("lx.in","r",stdin);

    t=readint();
    while(t--)
    {
        priority_queue<int>q1;//利用自带的优先队列(默认大根堆)
        priority_queue<int>q2;//每次直接定义比你每次清0快的多
        n=readint();
        for(int i=1;i<=n;i++) a[i]=readint();
        sort(a+1,a+n+1);
        tot=n/2;
        if(n%2==1) tot++;
        for(int i=1;i<=tot;i++) q1.push (a[i]);
        for(int i=tot+1;i<=n;i++) q2.push (-a[i]);//因为默认大根堆,所以变成负数后就成了一个小根堆,取出时再负回来
        m=readint();
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s+1);
            if(s[1]=='a')
            {
                x=readint();
                if(n%2==1)
                {
                    y=q1.top();q1.pop();
                    q1.push(min(x,y));
                    q2.push(-max(x,y));
                }
                else
                {
                    y=-q2.top();q2.pop();
                    q1.push(min(x,y));
                    q2.push(-max(x,y));
                }
                n++;
            }
            else
            {
                ans=q1.top();
                cout<<ans<<endl;
            }
        }
    }

    return 0;
}
发布了99 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qianguch/article/details/78277086