树状数组+二分
  • 板块P1801 黑匣子
  • 楼主Your_Name
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/20 21:03
  • 上次更新2024/9/20 21:42:42
查看原帖
树状数组+二分
681229
Your_Name楼主2024/9/20 21:03

为啥没人用离散化+树状数组+二分写呢?感觉思路是更好想的(当然没有set好想)。

代码如下

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
int c[N], a[N], u[N], n, m;
vector<int> x;
inline int lowbit(int x){
    return x & (-x);
}
inline void add(int x, int k){
    while(x <= N){
        c[x] += k;
        x += lowbit(x);
    }
}
inline LL ask(int x){
    LL ans = 0;
    while(x){
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
inline int find(int k){
    return lower_bound(x.begin(), x.end(), k) - x.begin() + 1;
}
int main(){
    cin >> m >> n;
    for(int i = 1; i <= m; i ++){
        cin >> a[i];
        x.push_back(a[i]);
    }
    sort(x.begin(), x.end());
    x.erase(unique(x.begin(), x.end()), x.end());
    for(int i = 1; i <= m; i ++)a[i] = find(a[i]);
    int now = 1;
    for(int i = 1; i <= n; i ++){
        cin >> u[i];
        while(now <= u[i]){
            add(a[now], 1);
            now ++;
        }
        LL l = 0, r = N, mid, an;
        while(l <= r){
            mid = l + r >> 1;
            an = ask(mid);
            if(an >= i)r = mid - 1;
            else l = mid + 1;
        }
        cout << x[l - 1] << endl;
    }
    return 0;
}
2024/9/20 21:03
加载中...