标签: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