1. 程式人生 > 其它 >P3871 [TJOI2010]中位數(對頂堆)

P3871 [TJOI2010]中位數(對頂堆)

題目傳送門

題意

給定一個N個元素組成的整數序列,有兩種操作:
1.add a 在該序列的最後新增一個整數a,新序列長度為n+1
2.mid 輸出當前序列的中位數

輸入格式

第一行為初始序列長度N。
第二行為N個整數,表示整數序列,數字之間用空格分隔。
第三行為運算元M,即要進行M次操作。
下面為M行,每行輸入格式如題意所述。

輸出格式

對於每個mid操作輸出中位數的值

樣例

input

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

output

5
13

思路

開兩個優先佇列,對頂堆。
從小到大排列的1~n/2的元素實時維護在第一個優先佇列(從大到小)中,剩下的元素維護在第二個優先佇列(從小到大)中。
當然也可以平衡樹啦(Orz)

code

#include <bits/stdc++.h>
using  namespace  std;

typedef long long ll;
typedef unsigned long long ull;
//#pragma GCC optimize(3)
#define pb push_back
#define is insert
#define PII pair<int,int>
#define show(x) cerr<<#x<<" : "<<x<<endl;
//mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
//ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}

const int INF=0x3f3f3f3f;//2147483647;
const int N=1e5+50,M=1e5+50;
const ll mod=998244353;

int n;
int a[N];
int m;
int mid;
priority_queue<int>ql;
priority_queue<int,vector<int>,greater<int>>qr;
void solve() {
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    cin>>m;
    int pos;
    if(n&1){
        mid=a[n/2+1];
        pos=n/2+1;
    }
    else {
        mid=min(a[n/2],a[n/2+1]);
        if(a[n/2]<=a[n/2+1]){
            pos=n/2;
        }
        else {
            pos=n/2+1;
        }
    }
    for(int i=1;i<=pos;i++){
        ql.push(a[i]);
    }
    for(int j=pos+1;j<=n;j++){
        qr.push(a[j]);
    }
    while(m--){
        string s;cin>>s;
        if(s[0]=='a'){
            int tmp;cin>>tmp;
            n++;
            if(tmp>mid){
                qr.push(tmp);
            }
            else {
                ql.push(tmp);
            }
            if(n&1){
                while(ql.size()>qr.size()){
                    int tmp=ql.top();
                    ql.pop();
                    qr.push(tmp);
                }
                while(ql.size()<qr.size()){
                    int tmp=qr.top();
                    qr.pop();
                    ql.push(tmp);
                }
                mid=ql.top();
            }
            else {
                while(ql.size()>qr.size()){
                    int tmp=ql.top();
                    ql.pop();
                    qr.push(tmp);
                }
                while(ql.size()<qr.size()){
                    int tmp=qr.top();
                    qr.pop();
                    ql.push(tmp);
                }
                int q1=ql.top();int q2=qr.top();
                if(q1<=q2){
                    mid=q1;
                }
                else {
                    mid=q2;
                }
            }
        }
        else {
            cout<<mid<<"\n";
        }
        //cout<<"mid="<<mid<<endl;
    }
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int __=1;//cin>>__;
    while(__--){
        solve();
    }
    return 0;
}