2104 (塊狀陣列(平面分割))
阿新 • • 發佈:2018-12-14
題解:靜態查詢區間第k小問題,此處使用塊狀陣列(平面分割)解決
附上程式碼:
#include<iostream> #include<cstdio> #include<vector> #include<algorithm> using namespace std; const int B=1000; const int MAX_N=1e5+50; const int MAX_M=5e3+50; int N,M; int A[MAX_N]; int I[MAX_N],J[MAX_N],K[MAX_N]; int nums[MAX_N]; vector<int>bucket[MAX_N/B]; void solve() { for(int i=0;i<N;i++){ bucket[i/B].push_back(A[i]); nums[i]=A[i]; } sort(nums,nums+N); for(int i=0;i<N/B;i++){ sort(bucket[i].begin(),bucket[i].end()); } for(int i=0;i<M;i++){ int l=I[i]-1,r=J[i],k=K[i]; int lb=-1,ub=N; while(ub-lb>1){ int md=(lb+ub)/2; int x=nums[md]; int tl=l,tr=r,c=0; while(tl<tr&&tl%B!=0){ if(A[tl++]<=x){ c++; } } while(tl<tr&&tr%B!=0){ if(A[--tr]<=x){ c++; } } while(tl<tr){ int b=tl/B; c+=upper_bound(bucket[b].begin(),bucket[b].end(),x)-bucket[b].begin(); tl+=B; } if(c>=k){ ub=md; }else{ lb=md; } } printf("%d\n",nums[ub]); } } int main() { scanf("%d%d",&N,&M); for(int i=0;i<N;i++){ scanf("%d",&A[i]); } for(int i=0;i<M;i++){ scanf("%d%d%d",&I[i],&J[i],&K[i]); } solve(); return 0; }