HDU2665 Kth number【主席樹】

Enjoy_process發表於2018-09-12

Kth number

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16583    Accepted Submission(s): 5076


 

Problem Description

Give you a sequence and ask you the kth big number of a inteval.

Input

The first line is the number of the test cases. 
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere. 
The second line contains n integers, describe the sequence. 
Each of following m lines contains three integers s, t, k. 
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]

Output

For each test case, output m lines. Each line contains the kth big number.

Sample Input

1 
10 1 
1 4 2 3 5 6 7 8 9 0 
1 3 2 

 Sample Output

2

Source

HDU男生專場公開賽——趕在女生之前先過節(From WHU)

題解:區間第K個數,靜態區間可使用劃分樹主席樹,使用主席樹的題解如下

AC的C++程式碼:

#include<iostream>
#include<algorithm>

using namespace std;
const int N=100010;
int a[N],b[N],rt[N*20],ls[N*20],rs[N*20],sum[N*20];

int id;
void build(int &o,int l,int r)
{
	o=++id;
	sum[o]=0;
	if(l==r) return;
	int m=(l+r)>>1;
	build(ls[o],l,m);
	build(rs[o],m+1,r);
}

void update(int &o,int l,int r,int last,int p)
{
	o=++id;
	ls[o]=ls[last];
	rs[o]=rs[last];
	sum[o]=sum[last]+1;
	if(l==r) return;
	int m=(l+r)>>1;
	if(p<=m)
	  update(ls[o],l,m,ls[last],p);
	else
	  update(rs[o],m+1,r,rs[last],p);
}

int query(int s,int e,int l,int r,int k)
{
	if(l==r) return l;
	int m=(l+r)>>1;
	int cnt=sum[ls[e]]-sum[ls[s]];
	if(cnt>=k)
	  return query(ls[s],ls[e],l,m,k);
	else
	  return query(rs[s],rs[e],m+1,r,k-cnt);
}

int main()
{
	int t,n,q,l,r,k;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&q);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			b[i]=a[i];
		}
		sort(b+1,b+1+n);
		int size=unique(b+1,b+1+n)-(b+1);
		id=0;
		build(rt[0],1,size);
		for(int i=1;i<=n;i++){
			a[i]=lower_bound(b+1,b+1+size,a[i])-b;
			update(rt[i],1,size,rt[i-1],a[i]);
		}
		while(q--){
			scanf("%d%d%d",&l,&r,&k);
			int pos=query(rt[l-1],rt[r],1,size,k);
			printf("%d\n",b[pos]);
		}
	}
	return 0;
}

 

相關文章