[练习][ZOJ3515]优先队列 Middle number

来源:互联网 发布:非结构化数据存储方案 编辑:程序博客网 时间:2024/06/07 22:21

题目描述
有一个整数序列,我们现在有两个操作:

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

分析:写两个优先队列,第一个到中位数放入que1,其余取负放入que2,由于优先队列默认大根堆,所以中位数在que1.top(),中位数后一个在que2.top(),所以在加入数的时候只需要判断z在哪一半,再微调中位数(比如说现在中位数是之前的中位数前一个,就把que1.top()取出来取负放到que2中,中位数是之前的中位数后一个,就把que2.top()取出来,但它现在是取了负的,所以再取负变成原数放到que1中),让这两个队列一直满足性质,查找时就输出que1.top()。

代码
写的有点冗长,因为是边思考边写的,用了很多判断,其实有些可以合并的orz,自己理解吧,无非就是讨论总个数为奇为偶的情况。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){    int sum=0,f=1;    char ch;    for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());    if(ch=='-')    {        f=-1;        ch=getchar();    }    for(;isdigit(ch);ch=getchar())        sum=(sum<<3)+(sum<<1)+ch-48;    return sum*f;}int T,n,m,x,y,z;int a[110010];char s[5];priority_queue<int> que1,que2; int main(){    freopen("mn.in","r",stdin);    freopen("mn.out","w",stdout);    T=getint();    while(T--)    {        while(!que1.empty())            que1.pop();        while(!que2.empty())            que2.pop();        n=getint();        for(int i=1;i<=n;++i)            a[i]=getint();        sort(a+1,a+n+1);        int mid=(n+1)/2;        for(int i=1;i<=mid;++i)            que1.push(a[i]);        for(int i=mid+1;i<=n;++i)            que2.push(-a[i]);        m=getint();        for(int i=1;i<=m;++i)        {            scanf("%s",s+1);            if(s[1]=='a')            {                z=getint();                x=que1.top();                y=-que2.top();                if(z>=y)                {                    if(n&1)                    {                        que2.push(-z);                        n++;                    }                    else                    {                        que2.pop();                        que2.push(-z);                        que1.push(y);                        n++;                    }                }                else if(z<=x)                {                    if(n&1)                    {                        que1.pop();                        que1.push(z);                        que2.push(-x);                        n++;                    }                    else                    {                        que1.push(z);                        n++;                    }                }                else                {                    if(n&1)                    {                        que2.push(-z);                        n++;                    }                    else                    {                        que1.push(z);                        n++;                    }                }            }            else            {                x=que1.top();                cout<<x<<'\n';            }        }    }    return 0;}

本题结。

原创粉丝点击