• 有序数列第K小


    有序数列第K小

    题目描述

    给出两个长度分别为(n,m)的单调非递减数列,求出它们合并后的第(k)小值。

    输入输出格式

    输入格式:

    第一行三个数,(n,m,k)如题意所述;

    第二行(n)个数,依次为数列1;

    第三行(m)个数,依次为数列2;

    输出格式:

    一个数,表示合并后的第(k)小值。

    说明

    对于所有数据,(kle n+mk≤n+m , a_ile 10^8),时间限制200ms。


    这个题其实考察的是(logk)的分治做法

    对当前的两个序列,左指针为(la,lb),右指针为(ra,rb),求当前的第(k)小值。

    把第(k)小值除2,取两个序列之一贡献这么多,得到子问题

    注意边界情况


    Code:

    #include <cstdio>
    int min(int x,int y){return x<y?x:y;}
    const int N=1000010;
    int n,m,k,a[N],b[N];
    void divide(int la,int ra,int lb,int rb,int nk)
    {
        if(la>ra)
        {
            printf("%d
    ",b[lb+nk-1]);
            return;
        }
        if(lb>rb)
        {
            printf("%d
    ",a[la+nk-1]);
            return;
        }
        if(nk==1)
        {
            printf("%d
    ",min(a[la],b[lb]));
            return;
        }    
        int lk=nk>>1;
        lk=min(lk,min(ra+1-la,rb+1-lb));
        if(a[la+lk-1]<b[lb+lk-1])
            divide(la+lk,ra,lb,rb,nk-lk);
        else
            divide(la,ra,lb+lk,rb,nk-lk);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++) scanf("%d",a+i);
        for(int i=1;i<=m;i++) scanf("%d",b+i);
        divide(1,n,1,m,k);
        return 0;
    }
    
    

    有序数列第K小加强版

    加上多次区间询问


    Code:

    #include <cstdio>
    int min(int x,int y){return x<y?x:y;}
    const int N=1000010;
    int n,m,q,a[N],b[N];
    void divide(int la,int ra,int lb,int rb,int nk)
    {
        if(la>ra)
        {
            printf("%d
    ",b[lb+nk-1]);
            return;
        }
        if(lb>rb)
        {
            printf("%d
    ",a[la+nk-1]);
            return;
        }
        if(nk==1)
        {
            printf("%d
    ",min(a[la],b[lb]));
            return;
        }
        int lk=nk>>1;
        lk=min(lk,min(ra+1-la,rb+1-lb));
        if(a[la+lk-1]<b[lb+lk-1])
            divide(la+lk,ra,lb,rb,nk-lk);
        else
            divide(la,ra,lb+lk,rb,nk-lk);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",a+i);
        for(int i=1;i<=m;i++) scanf("%d",b+i);
        scanf("%d",&q);
        int l1,l2,r1,r2,k;
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d%d%d%d",&l1,&r1,&l2,&r2,&k);
            divide(l1,r1,l2,r2,k);
        }
        return 0;
    }
    

    2018.7.26

  • 相关阅读:
    javascript初识
    css定位及叠放次序
    css精灵图
    css元素的显示及隐藏、文字隐藏
    css浮动
    盒子模型的边框、内边距、外边距、阴影
    css背景
    css中的显示与隐藏
    css定位
    css的布局与版心布局
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9369973.html
Copyright © 2020-2023  润新知