hdu_2665_Kth number(主席树)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2665
题意:给你一个区间,让你找这个区间第K大的数
题解:主席树模版题,也可以用划分树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }