hdu_2665_Kth number(主席树)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2665

题意:给你一个区间,让你找这个区间第K大的数

题解:主席树模版题,也可以用划分树

 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 #define FFC(i,a,b) for(int i=a;i<=b;++i)
 5 using namespace std;
 6 
 7 const int maxn=1e5+7;
 8 int root[maxn],a[maxn],cnt;
 9 vector<int>v;
10 struct node{int l,r,sum;}T[maxn*40];
11 int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
12 
13 void update(int l,int r,int &x,int y,int pos){
14     T[++cnt]=T[y],T[cnt].sum++,x=cnt;
15     if(l==r)return;
16     int mid=(l+r)>>1;
17     if(mid>=pos)update(l,mid,T[x].l,T[y].l,pos);
18     else update(mid+1,r,T[x].r,T[y].r,pos);
19 }
20 
21 int query(int l,int r,int x,int y,int k){
22     if(l==r)return l;
23     int mid=(l+r)>>1;
24     int sum=T[T[y].l].sum-T[T[x].l].sum;
25     if(sum>=k)return query(l,mid,T[x].l,T[y].l,k);
26     else return query(mid+1,r,T[x].r,T[y].r,k-sum);
27 }
28 int main(){
29     int t,m,n,x,y,k;
30     scanf("%d",&t);
31     while(t--){
32         v.clear();cnt=0;
33         scanf("%d%d",&n,&m);
34         FFC(i,1,n)scanf("%d",&a[i]),v.push_back(a[i]);
35         sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
36         FFC(i,1,n)update(1,n,root[i],root[i-1],getid(a[i]));
37         FFC(i,1,m)scanf("%d%d%d",&x,&y,&k),printf("%d\n",v[query(1,n,root[x-1],root[y],k)-1]);
38     }
39     return 0;
40 }
View Code

 

posted @ 2016-05-21 11:53  bin_gege  阅读(135)  评论(0编辑  收藏  举报