第一次尝试分桶法,很不顺利,还是太菜了。基本上是借鉴别人的代码,不过还是有很多地方不太懂
///分块思想本质是统计的方法 #include<cstdio> #include<algorithm> #include<vector> #include<iostream> #include<string> #include<cmath> const int N=1e5+5; const int S=1200; using namespace std; #define DEBUG(x) cout << #x << " = " << x << endl int a[N],num[N]; vector<int>vec[N/S]; int main(){ //freopen("in.txt","r",stdin); int n,q; scanf("%d%d",&n,&q); //DEBUG(npb); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); num[i]=a[i]; vec[i/S].push_back(a[i]); } sort(num+1,num+1+n); for(int i=0; i<(n-1)/S; i++) { sort(vec[i].begin(),vec[i].end()); } while(q--){ int L,R,K; scanf("%d%d%d",&L,&R,&K); int l=1,r=n,pos=0; while(l<=r){ int mid=(l+r)/2; int x=num[mid],tl=L,tr=R,cnt=0; ///统计的过程 while(tl<=tr&&tl/S==L/S){ if(a[tl++]<=x)cnt++; } while(tl<=tr&&tr/S==R/S){ if(a[tr--]<=x)cnt++; } while(tl<=tr){ int bn=tl/S; cnt+=upper_bound(vec[bn].begin(),vec[bn].end(),x)-vec[bn].begin(); tl+=S; } if(cnt>=K){ pos=mid,r=mid-1; } else l=mid+1; } printf("%d\n",num[pos]); } }
Q1:S的取值为什么是1200?我尝试了400,是错误的。刚开始我的想法是n开根号= =
参考资料
https://sea96.github.io/2017/05/21/%E5%B9%B3%E6%96%B9%E5%88%86%E5%89%B2/