【模板】主席树

模板连接

对于主席树,只要注意一点就好了:

空间$nlogn+mlogn$

空间$nlogn+mlogn$

空间$nlogn+mlogn$

$qwq$

$WA$了好几次,最后下狠心将空间开大$40$倍就过了$qwq$

主席树这么吃空间,

把经常爆栈的本宝宝吓的不敢再写了$qwq$ 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int a[1000010];
int t[1000010];
int x,y,k;

int lc[4000010];
int rc[4000010];
int num[4000010];
int root[4000010];
int len,siz;

void update(int pos,int &x,int l,int r,int val)
{
    x=++siz;
    num[siz]=num[pos]+1;
    lc[siz]=lc[pos];
    rc[siz]=rc[pos];
    if(l==r) return ;
    int mid=l+r>>1;
    val<=mid?update(lc[pos],lc[siz],l,mid,val):update(rc[pos],rc[siz],mid+1,r,val);
}

int query(int x,int y,int l,int r,int val)
{
    if(l==r) return t[l];
    int mid=l+r>>1;
    return num[lc[y]]>=val+num[lc[x]]?query(lc[x],lc[y],l,mid,val):query(rc[x],rc[y],mid+1,r,val-num[lc[y]]+num[lc[x]]);
}

inline void discretization()
{
    sort(t+1,t+n+1);
    len=unique(t+1,t+n+1)-t-1;
    for(int i=1;i<=n;i++)
      a[i]=lower_bound(t+1,t+len+1,a[i])-t,
      update(root[i-1],root[i],1,len,a[i]);
    return ;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),t[i]=a[i];
    discretization();
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&x,&y,&k),
        printf("%d\n",query(root[x-1],root[y],1,len,k));
    return 0;
}

 

posted @ 2018-07-21 22:08  米罗偕涯  阅读(394)  评论(0编辑  收藏  举报