Multiset

D. Multiset

后面才知道insert()的复杂度是\(O(n)\)的,所以 t 了很多次。

当需要进行很多次插入和删除第 k 位数这两种操作的时候,可以用树状数组来对其进行优化,c[i]表示的就是 i 这个数在当前序列里排的位置,求第 k 位数的大小可以用二分进行优化,这样复杂度就是\(O(log(log(n)))\)

// Created by CAD on 2020/5/17.
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define lowbit(i) (i&-i)
using namespace std;

const int maxn=1e6+5;
int c[maxn];
int n;
void add(int x,int k){
    while(x<=n) c[x]+=k,x+=lowbit(x);
}
int getsum(int x){
    int sum=0;
    while(x>0)
        sum+=c[x],x-=lowbit(x);
    return sum;
}

int main() {
    int q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i){
        int x;scanf("%d",&x);
        add(x,1);
    }
    while(q--){
        int x;scanf("%d",&x);
        if(x>0)	add(x,1);
        else{
            x=-x;
            int l=1,r=n;
            int ans=inf;
            while(l<=r){
                int mid= l + r >> 1;
                if(getsum(mid)>=x) ans=min(ans,mid),r=mid-1;
                else l=mid+1;
            }
            add(ans,-1);
        }
    }
    if(getsum(n)==0) cout<<0<<"\n";
    else{
        int l=1,r=n,x=1;
        int ans=inf;
        while(l<=r){
            int mid=(l+r)>>1;
            if(getsum(mid)>=x) ans=min(ans,mid),r=mid-1;
            else l=mid+1;
        }
        cout<<ans<<"\n";
    }
    return 0;
}
posted @ 2020-05-20 17:55  caoanda  阅读(199)  评论(0编辑  收藏  举报