51Nod【1686】——1686 第K大区间(尺取+二分)

原创 2016年08月28日 17:02:01
基准时间限制:1 秒 空间限制:131072 KB

定义一个区间的值为其众数出现的次数。
现给出n个数,求将所有区间的值排序后,第K大的值为多少。
众数(统计学/数学名词)_百度百科

Input

第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2)
第二行n个数,0<=每个数<2^31

Output

一个数表示答案。

Input示例

4 2
1 2 3 2

Output示例

2

看到一脸懵逼,后来发现看错题了。。。。。,由于值最后价值为[1,n],所以我们可以通过二分,去检查二分出来的值是否正确,大于它的是否为k-1个。检验的时候可以通过尺取的方式。

#include <bits/stdc++.h>
#define fread(x) freopen(x,"r",stdin)
#define fwrite(x) freopen(x,"w",stdout)
using namespace std;
typedef long long LL;
const int Max = 1e6;
LL arr[Max],a[Max];
int Ls[Max];
int n,k;
int num[Max];
bool ok(int s) {
    memset(num,0,sizeof(num));
    LL nu = 0; int L = 1;
    for(int i = 1;i<=n;i++ ){
        num[Ls[i]]++;
        if(num[Ls[i]] > s) {
            while(num[Ls[i]]> s) {
                nu+=(n-i+1);
                num[Ls[L++]]--;
            }
        }
        if(nu >= k) return false;
    }
    return nu<=k;
}
int Solve() {
    int L = 1,R = n,ans =  1;
    while(L<=R) {
        int mid = (L+R)>>1;
        if(ok(mid)) {
            ans = mid;
            R = mid-1;
        }
        else L = mid+1; 
    }
    return ans;
}
int main() {
    scanf("%d %d",&n,&k);
    for(int i =1 ; i<=n;i++) {
        scanf("%lld",&arr[i]);
        a[i] = arr[i];
    }
    sort(arr+1,arr+n+1);
    arr[0] = 1;
    for(int i = 2;i <= n;i++) if(arr[arr[0]] != arr[i]) arr[++arr[0]] = arr[i];
    for(int i = 1;i <= n;i++) Ls[i] = lower_bound(arr+1,arr+arr[0]+1,a[i])-arr;
    printf("%d\n",Solve());
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

51nod 1686 第K大区间【离散化+二分】

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686题意:定义一个区间的值为其众数出现的次数。 现给出n个数...
  • Yukizzz
  • Yukizzz
  • 2016年04月26日 10:23
  • 595

二分 51Nod1686 第K大区间

传送门:点击打开链接 题意:定义一个区间的值为其众数出现的次数。 现给出n个数,求将所有区间的值排序后,第K大的值为多少。 二分第k大的数是多少,设为m,之后的check,只需要计算有多少个区间...

51nod1686 第K大区间

题目描述1686 第K大区间 定义一个区间的值为其众数出现的次数。 现给出n个数,求将所有区间的值排序后,第K大的值为多少。Input第一行两个数n和k(1...

51Nod-1686-第K大区间

ACM模版描述题解十分有意思的二分,二分第k大的数是多少,设为mid,然后cala(mid),只要计算出有多少个区间的众数的次数是>= mid的即可。使用尺取法+二分可以实现O(nlogn)复杂度的算...
  • f_zyj
  • f_zyj
  • 2016年10月06日 00:28
  • 695

51nod 1686 想法

点击打开链接 题意:中文 思路:我们可以二分要求的那个次数,然后对于每次判断遍历整个数组求出大于等于mid的个数即可,用vector寸一下个数即可#include #include #incl...
  • Dan__ge
  • Dan__ge
  • 2016年10月26日 19:39
  • 161

【51nod】 第K大区间2(二分+树状数组)

【51nod】 第K大区间2(二分+树状数组) 第K大区间2 ﹡    LH (命题人) 基准时间限制:1.5 秒 空间限制:131072 KB 分值...

【主席树】51Nod 1175 区间中第K大的数

题面在这里主席树裸题……联赛快来了还是练练手速吧示例程序
  • linkfqy
  • linkfqy
  • 2017年10月30日 16:46
  • 500

51nod 1175 区间中第K大的数(主席树)

做的那俩是区间第k小,碰到个区间第k大的,顺手切掉。#include using namespace std;const int MAXN = 1e5+10; int num[MAXN],root[...

51nod1685:第K大区间2

1685 第K大区间2 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 定义一个长度为...

51nod——寻找第K大的数(C++版)

题目: 数组A和数组B,里面都有n个整数。数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1].......
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:51Nod【1686】——1686 第K大区间(尺取+二分)
举报原因:
原因补充:

(最多只允许输入30个字)