码迷,mamicode.com
首页 > 其他好文 > 详细

手撸主席树模板[静态区间第k大]

时间:2019-09-27 21:03:49      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:memcpy   clu   algo   build   while   can   区间   class   amp   

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn =2e5;
int tot,n,m;
int sum[(maxn << 5) + 10],rt[maxn + 10],ls[(maxn << 5) + 10],rs[(maxn << 5) + 10];
int a[maxn + 10],ind[maxn + 10],len;
inline int getid(const int &val){return lower_bound(ind + 1,ind + len + 1,val)-ind;}
int build(int l,int r)
{
    int root = ++tot;
    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 dir = ++tot;
    ls[dir] = ls[root],rs[dir] = rs[root],sum[dir] = sum[root] + 1;
    if(l == r)return dir;
    int mid = l + r >> 1;
    if(k <= mid)
        ls[dir] = update(k,l,mid,ls[dir]);
    else
        rs[dir] = update(k,mid + 1,r,rs[dir]);
    return dir;
}
int query(int u,int v,int l,int r,int k)
{
    int mid = l + r >> 1,x = sum[ls[v]] - sum[ls[u]];
    if(l == r)return l;
    if(k <= x)return query(ls[u],ls[v],l,mid,k);
    elsereturn query(rs[u],rs[v],mid + 1,r,k - x);
}
inline void init()
{
    scanf("%d%d",&n,&m);
    for(register int i = 1;i <= n;++i)
        scanf("%d",a + i);
    memcpy(ind,a,sizeof ind);
    sort(ind + 1,ind + n + 1);
    len = unique(ind + 1,ind + n + 1) - ind - 1;
    rt[0] = build(1,len);
    for(register int i = 1;i <= n;++i)
        rt[i] = update(getid(a[i]),1,len,rt[i - 1]);
}
int l,r,k;
inline void work(){
    while(m--){scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",ind[query(rt[l - 1],rt[r],1,len,k)]);
    }
}
int main()
{
    init();
    work();
    return 0;
}

手撸主席树模板[静态区间第k大]

标签:memcpy   clu   algo   build   while   can   区间   class   amp   

原文地址:https://www.cnblogs.com/wzxbeliever/p/11600220.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!