划分树
1.模板
1 const int N(1e5+5), H(log2(N)+2); 2 int a[H][N], toleft[H][N], sorted[N]; 3 4 void build(int h, int L, int R){ 5 if(L==R) return; 6 int mid=(L+R)>>1, nl=mid-L+1; 7 for(int i=L; i<=R; i++) nl-=a[h][i]<sorted[mid]; 8 for(int i=L, lp=L, rp=mid+1; i<=R; i++){ 9 if(a[h][i]<sorted[mid]) a[h+1][lp++]=a[h][i]; 10 else if(a[h][i]>sorted[mid]) a[h+1][rp++]=a[h][i]; 11 else nl? a[h+1][lp++]=a[h][i], --nl: a[h+1][rp++]=a[h][i]; 12 toleft[h][i]=toleft[h][L-1]+lp-L; 13 } 14 build(h+1, L, mid), build(h+1, mid+1, R); 15 } 16 17 int query(int h, int L, int R, int l, int r, int k){ 18 if(L==R) return a[h][L]; 19 int nl=toleft[h][r]-a[h][l-1], nr=r-l+1-nl, mid=(L+R)>>1; 20 if(nl>=k){ 21 l=L+toleft[h][l-1]-toleft[h][L-1], r=l+nl-1; 22 return query(h+1, L, mid, l, r, k); 23 } 24 r+=toleft[h][R]-toleft[h][r], l=r-nr+1; 25 return query(h+1, mid+1, R, l, r, k-nl); 26 } 27 28 int Rank(int h, int L, int R, int l, int r, int v){ 29 if(L==R) return a[h][L]<v; 30 int nl=toleft[h][r]-a[h][l-1], nr=r-l+1-nl, mid=(L+R)>>1; 31 if(sorted[mid]>=v){ 32 l=L+toleft[h][l-1]-toleft[h][L-1], r=l+nl-1; 33 return Rank(h+1, L, mid, l, r, v); 34 } 35 r+=toleft[h][R]-toleft[h][r], l=r-nr+1; 36 return nl+Rank(h+1, mid+1, R, l, r, v); 37 }
2.实现细节