洛谷 3834 【模板】可持久化线段树 1(主席树)

题目:https://www.luogu.org/problemnew/show/P3834

今天被可持久化数据结构虐了。我要学习可持久化数据结构。

抄抄抄模板。感觉其实挺好写的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,m,Q,a[N],b[N],ls[N<<5],rs[N<<5],sm[N<<5],t[N],tot;
int build(int l,int r)
{
  int rt=++tot;
  sm[rt]=0;//
  if(l<r)
    {
      int mid=l+r>>1;
      //      build(l,mid);build(mid+1,r);
      ls[rt]=build(l,mid);rs[rt]=build(mid+1,r);//
    }
  return rt;
}
int updt(int pre,int l,int r,int p)
{
  int rt=++tot;
  ls[rt]=ls[pre];rs[rt]=rs[pre];sm[rt]=sm[pre]+1;
  if(l<r)
    {
      int mid=l+r>>1;
      if(p<=mid){ls[rt]=updt(ls[pre],l,mid,p);}
      else {rs[rt]=updt(rs[pre],mid+1,r,p);}
    }
  return rt;
}
int query(int u,int v,int l,int r,int p)
{
  if(l>=r)return l;
  int k=sm[ls[v]]-sm[ls[u]],mid=l+r>>1;//ls!
  if(p<=k)return query(ls[u],ls[v],l,mid,p);//ls[] rs[] !!
  return query(rs[u],rs[v],mid+1,r,p-k);
}
int main()
{
  scanf("%d%d",&n,&Q);
  for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
  sort(b+1,b+n+1);m=unique(b+1,b+n+1)-b-1;
  t[0]=build(1,m);
  for(int i=1;i<=n;i++)
    {
      int tmp=lower_bound(b+1,b+m+1,a[i])-b;
      t[i]=updt(t[i-1],1,m,tmp);
    }
  for(int i=1,l,r,k;i<=Q;i++)
    {
      scanf("%d%d%d",&l,&r,&k);
      printf("%d
",b[query(t[l-1],t[r],1,m,k)]);//1,m,k--m!!
    }
  return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9332306.html