离散化+离线处理+线段树维护最小值+树状数组+二分查找

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using db = double;
#define int long long
const int N=2e5+5;
struct node{
    int data,cnt;
    node(){
        data=0,cnt=0;
    }
    node(int x,int y){
        data=x,cnt=y;
    }
    bool operator<(const node &x) const{
        if(data==x.data) return cnt<x.cnt;
        return data<x.data;
    }
};
node b[N];
int a[N];
int tree[N<<2];
int tag[N<<2];
int n,m;
int ls(int p) { return p << 1; }
int rs(int p) { return p << 1 | 1; }

void push_up(int p) {
    tree[p] = min(tree[ls(p)], tree[rs(p)]); 
}

void addtag(int p, int pl, int pr, int d) {
    tag[p] += d;
    tree[p] += d; 
}

void push_down(int p, int pl, int pr) {
    if (tag[p]) {
        int mid = (pl + pr) >> 1;
        addtag(ls(p), pl, mid, tag[p]);
        addtag(rs(p), mid + 1, pr, tag[p]);
        tag[p] = 0;
    }
}

void build(int p, int pl, int pr) {
    if (pl == pr) {
        tree[p] = a[pl];
        return;
    }
    int mid = (pl + pr) >> 1;
    build(ls(p), pl, mid);
    build(rs(p), mid + 1, pr);
    push_up(p);
}

void update(int L, int R, int p, int pl, int pr, int d) {
    if (L <= pl && pr <= R) {
        addtag(p, pl, pr, d);
        return;
    }
    push_down(p, pl, pr);
    int mid = (pl + pr) >> 1;
    if (L <= mid) update(L, R, ls(p), pl, mid, d);
    if (R > mid) update(L, R, rs(p), mid + 1, pr, d);
    push_up(p);
}

int query(int L, int R, int p, int pl, int pr) {
    if (L <= pl && pr <= R) {
        return tree[p];
    }
    push_down(p, pl, pr);
    int mid = (pl + pr) >> 1;
    int res = 1e9;
    if (L <= mid) res = min(res, query(L, R, ls(p), pl, mid));
    if (R > mid) res = min(res, query(L, R, rs(p), mid + 1, pr));
    return res;
}
#define lowbit(x) ((x)&-(x))
int t[N];
void add(int x,int d){
    while(x<=n){
        t[x]+=d;
        x+=lowbit(x);
    }
}
int sum(int x){
    int ans=0;
    while(x){
        ans+=t[x];
        x-=lowbit(x);
    }
    return ans;
}
signed main(){
    std::ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>b[i].data;
        b[i].cnt=i;
    }
    vector<int> v(n+1);
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++){
        v[b[i].cnt]=v[b[i-1].cnt];
        if(b[i].data!=b[i-1].data) v[b[i].cnt]++;
    }
    // for(int i=1;i<=n;i++){
    //     cout<<v[i]<<" ";
    // }
    // cout<<endl;
    for(int i=n;i>=1;i--){
        a[i]=sum(n)-sum(v[i]);
        add(v[i],1);
    }
    // for(int i=1;i<=n;i++){
    //     cout<<a[i]<<" ";
    // }
    build(1, 1, n);
    int q;
    cin>>q;
    vector<pii> ask(q+1);
    for(int i=1;i<=q;i++){
        cin>>ask[i].first;
        ask[i].second=i;
    }
    for(int i=1;i<=n;i++){
        v[i]=b[i].data;
    }
    sort(ask.begin()+1,ask.end());
    vector<int> ans(q+1);
    int pre=n;
    for(int i=q;i>=1;i--){
        auto [x,p]=ask[i];
        int pos=lower_bound(v.begin()+1,v.end(),x+1)-v.begin();
        // cout<<x<<" "<<pos<<endl;
        // cout<<pos<<pre<<endl;
        for(int j=pos;j<=pre;j++){
            // cout<<query(1,n,1,1,n)<<endl;
            // cout<<query(4,4,1,1,n)<<endl;
            // cout<<b[j].cnt<<endl;
            update(b[j].cnt+1,n,1,1,n,1);
            // cout<<query(1,n,1,1,n)<<endl;
            // cout<<query(4,4,1,1,n)<<endl;
        }
        // cout<<query(1,n,1,1,n)<<endl;
        ans[p]=query(1,n,1,1,n);
        pre=pos-1;
    }
    for(int i=1;i<=q;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
}