Советский бессмертный

LGOJ P3834 【模板】可持久化线段树 1(主席树)

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

struct node
{
	node *Lnode,*Rnode;
	int val;
	
	node()
	{
		Lnode=NULL;
		Rnode=NULL;
		val=0;
		
		return;
	}
	
	void clone(node* N)
	{
		Lnode=N->Lnode;
		Rnode=N->Rnode;
		val=N->val;
		
		return;
	}
}tree[3000005],*root[5005],*tail=tree;
int a[100005],b[100005];

node* build(int L,int R)
{
	node *O=(++tail);
	
	if(L==R) return O;
	
	int M=(L+R)>>1;
	
	O->Lnode=build(L,M);
	O->Rnode=build(M+1,R);
	
	return O;
}

node* modify(node* N,int L,int R,int pos)
{
	node *O=(++tail);
	
	O->clone(N);
	O->val++;
	
	if(L==R) return O;
	
	int M=(L+R)>>1;
	
	if(pos<=M) O->Lnode=modify(N->Lnode,L,M,pos);
	else O->Rnode=modify(N->Rnode,M+1,R,pos);
	
	return O;
}

int query(node* N,node* O,int L,int R,int pos)
{
	if(L==R) return L;
	
	int M=(L+R)>>1,npos=O->Lnode->val-N->Lnode->val;
	
	if(npos>=pos) return query(N->Lnode,O->Lnode,L,M,pos);
	return query(N->Rnode,O->Rnode,M+1,R,pos-npos);
}

int main()
{
	int n,m,cnt;
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		
		b[i]=a[i];
	}
	
	stable_sort(b+1,b+n+1);
	cnt=unique(b+1,b+n+1)-b-1;
	root[0]=build(1,cnt);
	for(int i=1;i<=n;i++)
	{
		int tmp=lower_bound(b+1,b+cnt+1,a[i])-b;
		
		root[i]=modify(root[i-1],1,cnt,tmp);
	}
	while(m--)
	{
		int i,j,k,p;
		
		scanf("%d%d%d",&i,&j,&k);
		
		p=query(root[i-1],root[j],1,cnt,k);
		
		printf("%d\n",b[p]);
	}
	
	return 0;
}
posted @ 2019-02-18 08:12  BIG_Showers  阅读(208)  评论(0)    收藏  举报