洛谷P3834 可持久化线段树

P3834
AC code

//静态区间第K小
//可持久化线段树
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 10;
struct node{
  int l,r,cnt;
}tree[maxn*40];

int n,m,x,y,z,t,tot;
int a[maxn],b[maxn];
int root[maxn];

int build(int l,int r){
  int p = ++tot;
  if(l==r){
    return p;
  }
  int mid = l + (r - l) / 2;
  tree[p].l = build(l,mid);
  tree[p].r = build(mid+1,r);
  return p;
}

int update(int now,int l,int r,int k){
  int p = ++tot;
  tree[p]=tree[now];
  tree[p].cnt++;
  if(l==r){
    return p;
  }
  int mid = l + (r - l) / 2;
  if(k<=mid){
    tree[p].l=update(tree[p].l,l,mid,k);
  }else{
    tree[p].r=update(tree[p].r,mid+1,r,k);
  }
  return p;
}

int query(int x,int y,int l,int r,int k){
  if(l==r){
    return l;
  }
  int mid = l + (r - l) / 2;
  int sum = tree[tree[y].l].cnt-tree[tree[x].l].cnt;
  if(sum>=k){
    return query(tree[x].l,tree[y].l,l,mid,k);
  }else{
    return query(tree[x].r,tree[y].r,mid+1,r,k-sum);
  }
}

int main(){
  while(~scanf("%d %d",&n,&m)){
    tot=0;
    for(int i=1;i<=n;i++){
      scanf("%d",&a[i]);
      b[i]=a[i];
    }
    sort(b+1,b+1+n);
    t=unique(b+1,b+1+n)-b-1;
    root[0]=build(1,t);
    for(int i=1;i<=n;i++){
      root[i]=update(root[i-1],1,t,lower_bound(b+1,b+1+t,a[i])-b);
    }
    while(m--){
      scanf("%d %d %d",&x,&y,&z);
      printf("%d\n",b[query(root[x-1],root[y],1,t,z)]);
    }
  }
  return 0;
}
发布了54 篇原创文章 · 获赞 28 · 访问量 7280

猜你喜欢

转载自blog.csdn.net/jiangkun0331/article/details/100056957
今日推荐