标签:sort 第k小 裸题 更新 numbers 多少 mit accept val
Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 51732 | Accepted: 17722 | |
Case Time Limit: 2000MS |
Description
Input
Output
Sample Input
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3
Sample Output
5 6 3
Hint
Source
#include<stdio.h> #include<algorithm> using namespace std; int tree[20][110001],sorted[110001],left[20][110001]; void build(int dep,int l,int r) { int mid=(l+r)>>1,i,midnum=mid-l+1,sonl=l,sonr=mid+1; for(i=l;i<=r;++i) if(sorted[i]<sorted[mid]) --midnum; //寻找能放入左子树中值的个数 for(i=l;i<=r;++i) { if(i==l) left[dep][i]=0; else left[dep][i]=left[dep][i-1]; //对不同的区间,进行左 //树个数初始化 if(tree[dep][i]==sorted[mid]) { if(midnum) { --midnum; ++left[dep][i]; tree[dep+1][sonl++]=tree[dep][i]; //统计进入左子树的个数,并更新//下一层树 } else tree[dep+1][sonr++]=tree[dep][i]; } else if(tree[dep][i]<sorted[mid]) //比中间值小,入左子树 { ++left[dep][i]; tree[dep+1][sonl++]=tree[dep][i]; } else tree[dep+1][sonr++]=tree[dep][i]; //比中间值小,入右子树 } if(l==r) return; //如果是叶子结点,返回 build(dep+1,l,mid); //递归左右子树 build(dep+1,mid+1,r); } int query(int dep,int l,int r,int ql,int qr,int k) { int l_ql,ql_qr,mid=(l+r)>>1; if(l==r) return tree[dep][l]; //如果找到值,返回 if(l==ql) //恰好是所求左区间为递归左区间 { // l_ql=0; ql_qr=left[dep][qr]; } else { l_ql=left[dep][ql-1]; //l到ql-1的入左区间数 ql_qr=left[dep][qr]-l_ql; //ql到qr的左区间数 } if(k<=ql_qr) return query(dep+1,l,mid,l+l_ql,l+l_ql+ql_qr-1,k); else //递归下一区间 return query(dep+1,mid+1,r,mid+1+ql-l_ql-l,mid+1+qr-ql_qr-l_ql-l,k-ql_qr); //右区间有点乱,ql-l-l_ql即l到ql-1中入右区间的个数依次类推 } int main() { int n,m,i,ql,qr,qk; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { scanf("%d",&tree[0][i]); sorted[i]=tree[0][i]; } sort(sorted+1,sorted+n+1); build(0,1,n); while(m--) { scanf("%d%d%d",&ql,&qr,&qk); printf("%d\n",query(0,1,n,ql,qr,qk)); } return 0; }
标签:sort 第k小 裸题 更新 numbers 多少 mit accept val
原文地址:http://www.cnblogs.com/fuermowei-sw/p/6213153.html