题目思路:划分数求第k小数。
[cpp] #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define inf 0x3f3f3f3f #define M 110000 int max(int a,int b) { return a>b a:b; } int min(int a,int b) { return a } int tr[20][M],s[20][M]; struct node { int id,num; bool operator<(const node a)const { return num } }p[M]; void build(int d,int l,int r) { if(l==r) return ; int i,j,k,mid; mid=(l+r)>>1; j=l;k=mid+1; for(i=l;i<=r;i++) { s[d][i]=s[d][i-1]; if(tr[d][i]<=mid) { s[d][i]++; tr[d+1][j++]=tr[d][i]; } else tr[d+1][k++]=tr[d][i]; } build(d+1,l,mid); build(d+1,mid+1,r); } int query(int d,int lp,int rp,int l,int r,int k) { if(lp==rp) return tr[d][lp]; int mid=(lp+rp)>>1; if(k<=s[d][r]-s[d][l-1]) { int lt=lp+s[d][l-1]-s[d][lp-1]; int rt=lp+s[d][r]-s[d][lp-1]-1; query(d+1,lp,mid,lt,rt,k); } else { int lt=mid+1+l-lp-(s[d][l-1]-s[d][lp-1]); int rt=mid+(r-lp+1)-(s[d][r]-s[d][lp-1]); query(d+1,mid+1,rp,lt,rt,k-(s[d][r]-s[d][l-1])); } } int main() { int t,l,r,i,n,m,k; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&p[i].num); p[i].id=i; } sort(p+1,p+n+1); for(i=1;i<=n;i++) { tr[0][p[i].id]=i; } for(i=0;i<20;i++) s[i][0]=0; build(0,1,n); while(m--) { www.2cto.com scanf("%d%d%d",&l,&r,&k); int tmp=query(0,1,n,l,r,k); printf("%d\n",p[tmp].num); } } }