码迷,mamicode.com
首页 > 其他好文 > 详细

Multiset

时间:2020-05-20 18:44:45      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:cad   ==   create   http   turn   names   ++   c++   inf   

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;
}

Multiset

标签:cad   ==   create   http   turn   names   ++   c++   inf   

原文地址:https://www.cnblogs.com/CADCADCAD/p/12925093.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!