poj2104

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MAX 100010
using namespace std;
int val[22][MAX];
int sorted[MAX];
int num[22][MAX];
void build(int d,int l,int r)
{
    if(l==r)return ;
    int mid=(l+r)>>1;
    int i;
    int same=0;
    int ln=l;
    int rn=mid+1;
    for(i=l;i<=r;i++)
      if(val[d][i]<sorted[mid])same++;
    same=mid-l+1-same;
    for(i=l;i<=r;i++)
    {
        if(i==l)
          num[d][i]=0;
        else
          num[d][i]=num[d][i-1];
        if(val[d][i]==sorted[mid]&&same)
        {
            --same;
            num[d][i]++;
            val[d+1][ln++]=val[d][i];
        }
        else
          if(val[d][i]<sorted[mid])
          {
              num[d][i]++;
              val[d+1][ln++]=val[d][i];
          }
          else
            val[d+1][rn++]=val[d][i];
    }
    build(d+1,l,mid);
    build(d+1,mid+1,r);
}
int query(int L,int R,int k,int l,int r,int d)
{
    if(l==r)return val[d][l];
    int m=(l+r)>>1,w1=0,w2=num[d][R];
    if(L>l)
      w1=num[d][L-1];
    w2-=w1;
    if(w2>=k)
      return query(l+w1,l+w1+w2-1,k,l,m,d+1);
    k-=w2;
    w1=L-l-w1;
    w2=R-L+1-w2;
    return query(m+w1+1,m+w1+w2,k,m+1,r,d+1);
}
int main()
{
    int m,n,x,y,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&sorted[i]);
            val[0][i]=sorted[i];
        }
        sort(sorted+1,sorted+1+n);
        build(0,1,n);
        while(m--)
        {
            scanf("%d%d%d",&x,&y,&k);
            printf("%d\n",query(x,y,k,1,n,0));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值