D. Multiset(带排名的数组数组)

Posted starve

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. Multiset(带排名的数组数组)相关的知识,希望对你有一定的参考价值。

题:https://codeforces.com/contest/1354/problem/D

题意:有个multiset,开始有n个数,有俩种操作,1、加入ki。2、删除集合中第k小的,问最后若这个集合大小不为0输出任意一个数,否则输出0;

分析:由于内存要求,不可用splay之类的数据结构,也有点大材小用,那么考虑用树状数组处理,这里有个排名的问题,要是我们知道排名的数是哪个就基本能用树状数组解决,下面是用前缀和的树状数组来得到排名k的数。

技术图片
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int inf =0x3f3f3f3f;
const int M=(1<<20);
const int N=(M)+6;
const double PI=3.1415926535;
int tr[N];
struct bit{
    void add(int x,int c){
        for(int i=x;i<N;i+=i&(-i))
            tr[i]+=c;
    }
    int kth(int k){
        int res=0;
        for(int i=(M>>1);i;i>>=1){
            if(tr[res+i]<k){
                k-=tr[res+i];
                res+=i;
            }
        }
        return res+1;
    }
}BIT;
int main(){
    int n,q;
    scanf("%d%d",&n,&q);
    for(int x,i=1;i<=n;i++){
        scanf("%d",&x);
        BIT.add(x,1);
    }
    while(q--){
        int k;
        scanf("%d",&k);
        if(k>0){
            BIT.add(k,1);
        }
        else{
            int tmp=BIT.kth(-k);
            ///cout<<tmp<<endl;
            BIT.add(tmp,-1);
        }
    }
    int ans=BIT.kth(1);
    if(ans>=M){
        printf("0");
    }
    else
        printf("%d",ans);
    return 0;
}
View Code

 

以上是关于D. Multiset(带排名的数组数组)的主要内容,如果未能解决你的问题,请参考以下文章

EC R 87 div2 D. Multiset 线段树 树状数组 二分

EC R 87 div2 D. Multiset 线段树 树状数组 二分

Round #504 D. Array Restoration .

D. Vasiliy's Multiset 异或字典树

D. Vasiliy‘s Multiset(01Trie)

[COGS 257]动态排名系统 树状数组套主席树