• COGS 930. [河南省队2012] 找第k小的数


    题目描述

    看到很短的题目会让人心情愉悦,所以给出一个长度为N的序列A1,A2,A3,...,AN,

    现在有M个询问,每个询问都是Ai...Aj中第k小的数等于多少。

    输入格式



    第一行两个正整数N,M。
    第二行N个数,表示序列A1,A2,...,AN。
    紧着的M行,每行三个正整数i,j,k(k≤j-i+1),表示

    询问Ai...Aj中第k小的数等于多少。

    输出格式

    共输出M行,第i行输出第i个询问的答案。

    样例输入1:

    4 3

    4 1 2 3

    1 3 1

    2 4 3

    1 4 4

    样例输出1:
    1
    3
    4



    样例输入2:
    5 5
    4 2 9 9 10
    1 3 1
    2 4 3
    1 4 4
    3 5 2
    2 5 2



    样例输出2:
    2
    9
    9
    9
    9



    注释:
    询问区间的第k小值并非严格第k小,例如样例2中第4个询问,询问3到5中第2小的数,
    答案输出9,并不是严格第2小的10。



    数据范围:
    在50%的数据中,1<=N<=10000,1<=M<=10000,A[i]<=100000;
    在100%的数据中,1<=N<=100000,1<=M<=100000,A[i]<=1000000;
    主席树求静态区间k大值模板

    屠龙宝刀点击就送

    #include <algorithm>
    #include <cstdio>
    #define N 100500
    using namespace std;
    struct cmt
    {
        int l,r,size;
    }tr[N*30];
    int n,m,rt[N],tot,a[N],b[N],size;
    int build(int l,int r)
    {
        int now=++tot;
        tr[now].size=0;
        if(l==r) return now;
        int mid=(l+r)>>1;
        tr[now].l=build(l,mid);
        tr[now].r=build(mid+1,r);
        return now;
    }
    inline int Rank(int x)
    {
        return lower_bound(b+1,b+1+size,x)-b;
    }
    void update(int l,int r,int x,int &y,int t)
    {
        y=++tot;
        tr[y].size=tr[x].size+1;
        if(l==r) return;
        tr[y].l=tr[x].l;
        tr[y].r=tr[x].r;
        int mid=(l+r)>>1;
        if(t<=mid) update(l,mid,tr[x].l,tr[y].l,t);
        else update(mid+1,r,tr[x].r,tr[y].r,t);
    }
    int ask(int l,int r,int lx,int rx,int k)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(tr[tr[rx].l].size-tr[tr[lx].l].size>=k) return ask(l,mid,tr[lx].l,tr[rx].l,k);
        else {k-=tr[tr[rx].l].size-tr[tr[lx].l].size;return ask(mid+1,r,tr[lx].r,tr[rx].r,k);}
    }
    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",&a[i]),b[i]=a[i];
        sort(b+1,b+1+n);
        size=unique(b+1,b+1+n)-b-1;
        rt[0]=build(1,size);
        for(int i=1;i<=n;++i) update(1,size,rt[i-1],rt[i],Rank(a[i]));
        for(int l,r,k;m--;)
        {
            scanf("%d%d%d",&l,&r,&k);
            printf("%d
    ",b[ask(1,size,rt[l-1],rt[r],k)]);
        }
        return 0;
    }
    int sb=Main();
    int main(int argc,char *argv[]) {;}
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    php面试题-2
    排序算法-1
    php面试题-1
    ES6基础-4
    ES6基础-3
    mysql优化-1
    ES6基础-2
    vuecli 项目进行gzip压缩 使页面加载速度更快
    vueCli3 项目创建时,git bash 箭头选择无效问题
    gulp4简单用法和问题总结
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7413886.html
Copyright © 2020-2023  润新知