比赛 |
20120718 |
评测结果 |
AAAAAAAAAA |
题目名称 |
找第k小的数 |
最终得分 |
100 |
用户昵称 |
kaaala |
运行时间 |
0.723 s |
代码语言 |
C++ |
内存使用 |
19.01 MiB |
提交时间 |
2012-07-18 09:38:04 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int l,r;
int mid(){return ((r+l)>>1);}
}tree[400040];
int len,so[100010],tf[20][100010],val[20][100010],N,M;
void build(int l,int r,int d,int u)
{
tree[u].l=l;
tree[u].r=r;
if(l==r)
return;
int mid=tree[u].mid(),ls=mid-l+1;
for(int i=l;i<=r;i++)
if(val[d][i]<so[mid])
ls--;
int lch=l,rch=mid+1,s=0;
for(int i=l;i<=r;i++)
{
if(i==l)
tf[d][i]=0;
else
tf[d][i]=tf[d][i-1];
if(val[d][i]<so[mid])
{
tf[d][i]++;
val[d+1][lch++]=val[d][i];
}
else if(val[d][i]>so[mid])
val[d+1][rch++]=val[d][i];
else if(s<ls)
{
s++;
tf[d][i]++;
val[d+1][lch++]=val[d][i];
}
else
val[d+1][rch++]=val[d][i];
}
build(l,mid,d+1,u*2);
build(mid+1,r,d+1,u*2+1);
}
int Find_kth(int l,int r,int k,int d,int u)
{
if(l==r)
return val[d][l];
int sln,slln;
if(l==tree[u].l)
{
sln=tf[d][r];
slln=0;
}
else
{
sln=tf[d][r]-tf[d][l-1];
slln=tf[d][l-1];
}
if(sln>=k)
{
int ll=tree[u].l+slln,rr=tree[u].l+slln+sln-1;
return Find_kth(ll,rr,k,d+1,u*2);
}
else
{
int mid=tree[u].mid(),srrn=l-tree[u].l-slln,srn=r-l+1-sln;
int ll=mid+srrn+1,rr=mid+srrn+srn;
return Find_kth(ll,rr,k-sln,d+1,u*2+1);
}
}
int main()
{
freopen("kth.in","r",stdin);
freopen("kth.out","w",stdout);
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
{
scanf("%d",&val[0][i]);
so[i]=val[0][i];
}
sort(so+1,so+1+N);
build(1,N,0,1);
while(M--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",Find_kth(l,r,k,0,1));
}
return 0;
}