主席树入门野生动物园

有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域
都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强
。饲养员cmdButtons决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子
进行投喂。值得注意的是,cmdButtons不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此cmdButtons
的投喂区间是互不包含的。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。
Input
输入文件第一行有两个数N和M。此后一行有N个数,从南到北描述狮子的觅食能力值。此后M行,每行描述一次投喂
。第t+2的三个数I,J,K表示在第t次投喂中,cmdButtons选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。
1<=N<=100000,1<=M<=50000
Output
有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。
Sample Input
7 2
1 5 2 6 3 7 4
1 5 3
2 7 1
Sample Output
3
2

 

#include<bits/stdc++.h>
#include<algorithm>
#define N 100010
using namespace std;
int sum[N*20],rt[N*20],ch[N*20][2],a[N],b[N],n,m,tot;
void build(int &now,int l,int r)
{
	now=++tot;
	sum[now]=0;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(ch[now][0],l,mid);
	build(ch[now][1],mid+1,r);
}
void update(int &now,int l,int r,int last,int p)
//now结点的编号,l,r左右边界,last上一个树对应结点的编号(根对根,左对左,右对右)
//p要加入的值 
{
	now=++tot;//新开一个结点出来,并复制上一个树的左右结点 
	ch[now][0]=ch[last][0];
	ch[now][1]=ch[last][1];
	sum[now]=sum[last]+1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	if(p<=mid)
	   update(ch[now][0],l,mid,ch[last][0],p);
	else 
	    update(ch[now][1],mid+1,r,ch[last][1],p);
}
int query(int l,int r,int x,int y,int k)
{
	if(l==r)return l;
	int mid=(l+r)>>1;
	int cnt=sum[ch[y][0]]-sum[ch[x][0]];
	if(k<=cnt)
	   return query(l,mid,ch[x][0],ch[y][0],k);
	else 
	   return query(mid+1,r,ch[x][1],ch[y][1],k-cnt);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]),b[i]=a[i];
	sort(b+1,b+n+1);
	int tt=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++)
	    a[i]=lower_bound(b+1,b+n+1,a[i])-b;
	build(rt[0],1,tt);
	for(int i=1;i<=n;i++)
	     update(rt[i],1,tt,rt[i-1],a[i]);
//	for (int i=0;i<=n;i++)
//	cout<<i<<"    "<<rt[i]<<endl;
	while(m--)
	{
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		printf("%d\n",b[query(1,tt,rt[x-1],rt[y],k)]);
	}
}

/*
7 2
1 5 2 6 3 7 4
1 5 3
2 7 1

rt[0]...1
rt[1]...14
rt[2]...18
rt[3]...22
rt[4]...26
rt[5]...30
rt[6]...34
rt[7]...37
*/ 

  

posted @ 2019-11-03 21:38  我微笑不代表我快乐  阅读(109)  评论(0编辑  收藏  举报