标签:
划分树:原理: 划分树的建树过程基本就是模拟快排过程,取一个已经排过序的区间中值,然后把小于中值的点放左边,大于的 放右边。
HDU 2665 Kth number(划分树入门题,纯套模板)
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<string> #include<map> #include<set> #include<queue> #include<vector> #include<stack> #include<cstdlib> using namespace std; const int maxn=100010; int A[maxn]; int tree[25][maxn]; int sum[25][maxn]; void build(int c,int l,int r) { if(l==r) return ; int mid=(l+r)>>1; int same=mid+1-l; for(int i=l;i<=r;i++){ if(tree[c][i]<A[mid]) same--; } int sl=l; int sr=mid+1; for(int i=l;i<=r;i++){ if(tree[c][i]<A[mid]){ tree[c+1][sl++]=tree[c][i]; } else if(tree[c][i]==A[mid]&&same>0){ tree[c+1][sl++]=tree[c][i]; same--; } else{ tree[c+1][sr++]=tree[c][i]; } sum[c][i]=sum[c][l-1]+sl-l; } build(c+1,l,mid); build(c+1,mid+1,r); } int query(int c,int L,int R,int l,int r,int k){ if(l==r) return tree[c][l]; int mid=(L+R)>>1; int cnt=sum[c][r]-sum[c][l-1]; if(cnt>=k){ int newl=L+sum[c][l-1]-sum[c][L-1]; int newr=newl+cnt-1; return query(c+1,L,mid,newl,newr,k); } else{ int newr=r+sum[c][R]-sum[c][r]; int newl=newr-(r-l-cnt); return query(c+1,mid+1,R,newl,newr,k-cnt); } } int main() { #ifndef ONLINE_JUDGE freopen("in.cpp","r",stdin); #endif // ONLINE_JUDGE int n,m; int T; cin>>T; while(T--){ scanf("%d%d",&n,&m); memset(tree,0,sizeof tree); for(int i=1;i<=n;i++){ scanf("%d",&A[i]); tree[0][i]=A[i]; } sort(A+1,A+n+1); build(0,1,n); int s,t,k; while(m--){ scanf("%d%d%d",&s,&t,&k); printf("%d\n",query(0,1,n,s,t,k)); } } return 0; }相关题型:hdu 4417 hdu 3473 hdu 2665 hdu 4215
标签:
原文地址:http://blog.csdn.net/u013514722/article/details/46520093