CF1354D - Multiset(数据结构,数状数组)

Description

思路

就是要你实现一个求第k大数的数据结构,大水题。由于空间比较吃紧,所以使用树状数组来实现。这里也当作记录一个模板。
树状数组求第k大数有 \(log_2n\) 的实现方法,十分巧妙。

也可以用线段树实现,甚至不用动态开点。只要能一个数组实现就可以。

实现

用贪心的思想,按二进制位从大到小判断。详见代码。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
#define inf 0x3f3f3f3f
 
int tarr[N];
int n;
 
int lowbit(int x) {return x & -x;}
void add(int p, int v) {
    while(p <= n) {
        tarr[p] += v;
        p += lowbit(p);
    }    
}
 
int query(int p) { //小于等于 //获得第p大的数
    int res = 0, cnt = 0;
    for(int i = 20; i >= 0; i--) {
        if(res + (1 << i) <= n && cnt + tarr[res + (1 << i)] < p) {
            cnt += tarr[res + (1 << i)];
            res += (1 << i);
            
        }
    }
    return res + 1;
}
 
 
int main() {
    ios::sync_with_stdio(false);
    int q;
    cin >> n >> q;
    for(int i = 1; i <= n; i++) {
        int v;
        cin >> v;
        add(v, 1);
    }
    int cnt = n;
    while(q--) {
        int v;
        cin >> v;
        if(v > 0) {
            add(v, 1);
            cnt++;
        } else {
            add(query(-v), -1);
            cnt--;
        }
    }
    if(!cnt) cout << "0" << endl;
    else cout << query(1) << endl;
    
}

猜你喜欢

转载自www.cnblogs.com/limil/p/12913397.html
今日推荐