主席树模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
int len=0,n,m,a[2001000],sum[2000100],hash[2001000],l[2000100],root[2000100],r[2000100];
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
void init()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){scanf("%d",&a[i]);hash[i]=a[i];}
}
int maketree(int L,int R)
{
	int rt=++len;
	int mid=(L+R)>>1;
	sum[rt]=0;
	if(L<R)
	{
		l[rt]=maketree(L,mid);
		r[rt]=maketree(mid+1,R);
	}
	return rt;
}
int update(int pre,int L,int R,int x)
{
	int rt=++len;
	l[rt]=l[pre];r[rt]=r[pre];sum[rt]=sum[pre]+1;
	if(L<R)
	{
		int mid=(L+R)>>1;
		if(x<=mid)l[rt]=update(l[pre],L,mid,x);
		else r[rt]=update(r[pre],mid+1,R,x);
	}
	return rt;
}
int query(int u,int v,int L,int R,int k)
{
	if(L>=R)return L;
	int mid=(L+R)>>1;
	int num=sum[l[v]]-sum[l[u]];
	if(num>=k)return query(l[u],l[v],L,mid,k);
	else return query(r[u],r[v],mid+1,R,k-num);
}
int main()
{
	//freopen("xf.in","r",stdin);
	init();
	sort(hash+1,hash+n+1);
	int d=unique(hash+1,hash+n+1)-(hash+1);
	root[0]=maketree(1,d);
	for(int i=1;i<=n;i++)
	{
		int x=lower_bound(hash+1,hash+d+1,a[i])-hash;
		root[i]=update(root[i-1],1,d,x);
	}
	while(m--)
	{
		int L,R,k;
		L=read();R=read();k=read();
		printf("%d\n",hash[query(root[L-1],root[R],1,d,k)]);
	}
	return 0;
}

  

posted @ 2018-03-12 14:45  mybing  阅读(109)  评论(0编辑  收藏  举报