zoukankan      html  css  js  c++  java
  • hdu 6231 -- K-th Number(二分+尺取)

    题目链接

    Problem Description
    Alice are given an array A[1..N] with N numbers.

    Now Alice want to build an array B by a parameter K as following rules:

    Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than K, then ignore this interval. Otherwise, find the K-th largest number in this interval and add this number into array B.

    In fact Alice doesn't care each element in the array B. She only wants to know the M-th largest element in the array B. Please help her to find this number.
     
    Input
    The first line is the number of test cases.

    For each test case, the first line contains three positive numbers N(1N105),K(1KN),M. The second line contains N numbers Ai(1Ai109).

    It's guaranteed that M is not greater than the length of the array B.
     
    Output
    For each test case, output a single line containing the M-th largest element in the array B.
     
    Sample Input
    2
    5 3 2
    2 3 1 5 4
    3 3 1
    5 8 2
     
    Sample Output
    3
    2

    题意:有个数列包含n个数,现在从这个数列中取出所有子区间中的第k大的数(所有长度大于等于k的子区间),构成一个新的数列,求这个新的数列的第M大的数?

    思路:我们可以利用尺取求出区间第k大数大于等于x的这样的区间有多少个,然后根据这个进行二分求出准确的第M大数,时间复杂度O(n*log n)。

    代码如下:

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N=1e5+5;
    int a[N],b[N];
    
    LL get(int x,int n,int k)
    {
        LL ans=0;
        int pos=1;
        int num=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>=x) num++;
            if(num==k)
            {
                ans+=n-i+1;
                while(a[pos]<x)
                {
                    ans+=n-i+1;
                    pos++;
                }
                num--; pos++;
            }
        }
        return ans;
    }
    
    int main()
    {
        int T; cin>>T;
        while(T--)
        {
            int n,k;
            LL m;
            scanf("%d%d%lld",&n,&k,&m);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]), b[i]=a[i];
            sort(b+1,b+n+1);
            int num=unique(b+1,b+n+1)-(b+1);
            int L=1,R=num;
            while(L<=R)
            {
                int mid=(L+R)>>1;
                LL tmp=get(b[mid],n,k);
                if(tmp<m) R=mid-1;
                else L=mid+1;
            }
            printf("%d
    ",b[L-1]);
        }
        return 0;
    }
  • 相关阅读:
    RocketMQ架构和源码分析
    RocketMQ问题总结
    整型和浮点型
    uvaoj 113
    Processing多窗口程序范例(一)
    Kotlin编写Processing程序(使用函数式编程思维和面向接口方式)
    浅谈Processing中的 println() 打印输出函数[String]
    Processing中获取表格数据( .tsv.csv )的经验分享
    Processing 网格(棋盘格)无限偏移纹理动画
    Processing 使用pixels[]像素数组绘制矩形rect和圆形ellipse
  • 原文地址:https://www.cnblogs.com/chen9510/p/7821624.html
Copyright © 2011-2022 走看看