[HDOJ2665] Kth number

匿名 (未验证) 提交于 2019-12-02 23:52:01

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 nn and mm (nn, mm <= 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,ks, t, k.
[ss,tt] indicates the interval and kk indicates the kth big number in interval [ss,tt]

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 

大意
一定是我英语不好
给定一个长为nn的数组,有mm次询问,每次询问输入一个区间[l,r][l,r]及一个kk,输出区间[l,r][l,r]内第kkС的数字。

˼·
静态区间第kk大(小),主席树板子。

AC代码

#include<stdio.h> #include<map> #include<queue> #include<iostream> #include<algorithm> #include<vector> #include<stack> #define MOD 10000000007 #define N 100005 typedef long long LL; using namespace std; typedef struct node{ 	int lson,rson,va;//va:权值   主席树  }node; int tot,n,m,te,len,s,t,k; int a[N],T[N]; node tree[N<<5]; int R[N]; void init() { 	for(int i=1;i<=n;i++) 	{ 		scanf("%d",&a[i]);T[i]=a[i]; 	} 	sort(T+1,T+n+1); 	len=unique(T+1,T+n+1)-T-1; } void build(int &root,int l,int r) { 	root=++tot; 	if(l==r)return; 	int mid=(l+r)/2; 	build(tree[root].lson,l,mid); 	build(tree[root].rson,mid+1,r); 	return; } int find(int target) { 	return lower_bound(T+1,T+len+1,target)-T; } void insert(int pre,int &root,int l,int r,int pos) { 	tree[++tot]=tree[pre];root=tot; 	if(l==r)  	{ 		tree[root].va++;return; 	} 	int mid=(l+r)/2; 	if(pos>mid) insert(tree[root].rson,tree[root].rson,mid+1,r,pos);else insert(tree[root].lson,tree[root].lson,l,mid,pos); 	tree[root].va++; 	return; } int query(int from,int to,int k,int l,int r) { 	if(l==r)return l; 	int sum=tree[tree[to].lson].va-tree[tree[from].lson].va; 	int mid=(l+r)/2; 	if(k>sum) 		return query(tree[from].rson,tree[to].rson,k-sum,mid+1,r); 	else  		return query(tree[from].lson,tree[to].lson,k,l,mid); } int main() { 	scanf("%d",&te); 	while(te--) 	{ 		scanf("%d%d",&n,&m); 		init(); 		tot=0; 		build(R[0],1,n); 		for(int i=1;i<=n;i++) insert(R[i-1],R[i],1,len,find(a[i]));//insert函数实际上是将原始数据离散化后的值插入权值线段树,故此时的l=1,r=离散化后剩余的元素数  		for(int i=1;i<=m;i++) 		{ 			scanf("%d%d%d",&s,&t,&k); 			printf("%d\n",T[query(R[s-1],R[t],k,1,len)]); 		} 	} 	return 0; }  
文章来源: https://blog.csdn.net/weixin_44582673/article/details/97259784
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!