比赛 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;
}