主席树(区间第k大值)

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
int n, m, k, cnt;
int ls[N<<5], rs[N<<5], sum[N<<5], rt[N<<5];
int a[N], b[N];
int build(int l, int r){
    int root = ++ cnt;
    if(l == r) return root;
    int mid = (l + r) >> 1;
    ls[root] = build(l, mid);
    rs[root] = build(mid + 1, r);
    return root;
}
int update(int k, int l, int r, int root){
    int id = ++ cnt;
    ls[id] = ls[root]; rs[id] = rs[root]; sum[id] = sum[root] + 1;
    if(l == r) return id;
    int mid = (l + r) >> 1;
    if(k <= mid) ls[id] = update(k, l, mid, ls[id]);
    if(k > mid) rs[id] = update(k, mid + 1, r, rs[id]);
    return id;
}
int query(int k, int u, int v, int l, int r)//查询区间第k小值
{
    int mid = (l + r) >> 1;
    int x = sum[ls[v]] - sum[ls[u]];
    if(l == r) return l;
    if(k <= x) return query(k, ls[u], ls[v], l, mid);
    if(k > x) return query(k - x, rs[u], rs[v], mid + 1, r);
}
int ask(int k, int u, int v, int l, int r)//查询区间小于等于k的数的个数
{
    if(k >= b[r]) return sum[v] - sum[u];
    if(k < b[l]) return 0;
    int ans = 0;
    int mid = (l + r) >> 1;
    if(k <= b[mid]) ans += ask(k, ls[u], ls[v], l, mid);
    else
    {
        ans += sum[ls[v]] - sum[ls[u]];
        ans += ask(k, rs[u], rs[v], mid + 1, r);
    }
    return ans;
}
void init()
{
    memset(sum,0,sizeof sum);
    cnt=k=0;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int _,n,kk;
    cin>>_;
    while(_--)
    {
        init();
        cin>>n>>kk;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            b[i]=a[i];
        }
        sort(b + 1, b + 1 + n);
        int len = unique(b + 1, b + 1 + n) - b - 1;
        rt[0] = build(1, len);
        for(int i = 1 ; i <= n ; ++ i)
        {
            int x = lower_bound(b + 1, b + 1 + len, a[i]) - b;
            rt[i] = update(x, 1, len, rt[i-1]);
        }
        ask(i,rt[ln-1],rt[rn],1,len);
        b[query(l-1, rt[ln-1], rt[rn], 1, len)];
    }
    return 0;
}

 

posted @ 2019-07-27 20:25  Suiyue_Li  阅读(314)  评论(0编辑  收藏  举报