ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Multiset

2020-05-20 18:07:44  阅读:271  来源: 互联网

标签:int mid else add getsum ans 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;
}

标签:int,mid,else,add,getsum,ans,Multiset
来源: https://www.cnblogs.com/CADCADCAD/p/12925093.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有