K-th Number(题面原来就是英文,不是我改的)

K-th Number(题面原来就是英文,不是我改的)

Background

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment.

Description

That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.

Format

Input

The first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000).
The second line contains n different integer numbers not exceeding 10^9 by their absolute values --- the array for which the answers should be given.
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).

Output

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample 1

Input

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

Output

5
6
3

Limitation

1s, 65536KiB for each test case.

Hint

C++ Code

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <limits>
#include <string>
#include <sstream>
using namespace std;

const int oo_min=0xcfcfcfcf,oo_max=0x3f3f3f3f;

int n,m,st_size;
int a[100000+1];
int s[100000+1];
int st_t[2000000+1];
int st_l[2000000+1];
int st_r[2000000+1];
int st_mid[2000000+1];
int st_lc[2000000+1];
int st_rc[2000000+1];
int st_sum[2000000+1];

int cmp_1(int x,int y)
{
    return x<y;
}

void build_st_1(int &now,int l,int r)
{
    now=++st_size;
    st_l[now]=l;
    st_r[now]=r;
    st_mid[now]=(l+r)/2;
    if (l<r)
    {
        if (l<=st_mid[now])
            build_st_1(st_lc[now],l,st_mid[now]);
        if (st_mid[now]+1<=r)
            build_st_1(st_rc[now],st_mid[now]+1,r);
    }
}

void copy_1(int now,int last)
{
    st_l[now]=st_l[last];
    st_r[now]=st_r[last];
    st_mid[now]=st_mid[last];
    st_lc[now]=st_lc[last];
    st_rc[now]=st_rc[last];
    st_sum[now]=st_sum[last];
}

void update_st_1(int &now,int last,int p)
{
    now=++st_size;
    copy_1(now,last);
    st_sum[now]++;
    if (st_l[now]<st_r[now])
    {
        if (p<=st_mid[now])
            update_st_1(st_lc[now],st_lc[last],p);
        else if (st_mid[now]+1<=p)
            update_st_1(st_rc[now],st_rc[last],p);
    }
}

int ask_st_sum_1(int now,int last,int th)
{
    if (st_lc[now]==st_rc[now])
        return s[st_l[now]];
    else
    {
        int temp=st_sum[st_lc[now]]-st_sum[st_lc[last]];
        if (temp>=th)
            return ask_st_sum_1(st_lc[now],st_lc[last],th);
        else if (temp<th)
            return ask_st_sum_1(st_rc[now],st_rc[last],th-temp);
    }
}

int main()
{
    while (~scanf("%d%d",&n,&m))
    {
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memcpy(s,a,sizeof(s));
        sort(&s[1],&s[n+1],cmp_1);
        st_size=0;
        memset(st_t,0,sizeof(st_t));
        memset(st_l,0,sizeof(st_l));
        memset(st_r,0,sizeof(st_r));
        memset(st_mid,0,sizeof(st_mid));
        memset(st_lc,0,sizeof(st_lc));
        memset(st_rc,0,sizeof(st_rc));
        memset(st_sum,0,sizeof(st_sum));
        build_st_1(st_t[st_size],1,n);
        for (int i=1;i<=n;i++)
        {
            int p=lower_bound(&s[1],&s[n+1],a[i])-(&s[0]);
            update_st_1(st_t[i],st_t[i-1],p);
        }
        for (int i=1;i<=m;i++)
        {
            int l,r,th;
            scanf("%d%d%d",&l,&r,&th);
            printf("%d\n",ask_st_sum_1(st_t[r],st_t[l-1],th));
        }
    }
}

Source

Vijos Original

信息

难度
9
分类
数据结构 | 平衡树线段树函数式编程 点击显示
标签
递交数
12
已通过
3
通过率
25%
上传者

相关

在下列训练计划中:

可持久化线段树

在下列比赛中:

sky1231的域的全部舊題目