zoukankan      html  css  js  c++  java
  • 51nod 1686 第K大区间【离散化+二分】

    题目链接:

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686

    题意:

    定义一个区间的值为其众数出现的次数。
    现给出n个数,求将所有区间的值排序后,第K大的值为多少。

    分析:

    二分答案,对于每个值判断大于等于该值的区间个数是否大于等于K
    判断某个值mid时枚举右端点,找到使得以该右端点为众数的最大的左端点。那么该区间就是满足题意的一个最小的区间之一,再加上前面的区间外的元素,就可以得到右端点为该点的满足条件的区间数。这样保证了任何被加进去的区间中的众数至少为mid。

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 1e5 + 5;
    int a[maxn], b[maxn];
    int cnt[maxn];
    int n;
    long long k;
    
    bool judge(int mid)
    {
        long long ans = 0;
        int  l = 1;
        bool flg = false;
        memset(cnt, 0,  sizeof(cnt));
        for(int i = 1; i <= n; i++){
            cnt[a[i]]++;
            if(cnt[a[i]] >= mid){
                flg = true;
                if(cnt[a[i]] > mid){
                    l++;
                    cnt[a[i]]--;
                }
                while(a[l] != a[i]){
                    l++;
                    cnt[a[l]]--;
                }
            }
            if(flg)  ans += l;
        }
        return ans >= k;
    }
    int main (void)
    {
        cin>>n>>k;
        int maxx = 0;
        for(int i = 1 ;i <= n; i++){
                cin>>a[i];
                b[i] = a[i];
        }
        sort(b + 1, b +1 + n);
        int t = unique(b + 1, b + n + 1) - (b + 1);
        for(int i = 1; i <= n; i++){
            a[i] = lower_bound(b + 1, b + t + 1, a[i]) - (b + 1);
        }
        int l = 1, r = n + 1;
        while(l + 1 < r){
            int mid = l + r>>1;
            if(judge(mid)) l = mid;
            else r =mid;
        }
        cout<<l<<endl;
        return 0;
    }
  • 相关阅读:
    熟悉常用的HDFS操作
    爬虫大作业-爬取B站弹幕
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    理解MapReduce
    熟悉常用的HBase操作
    熟悉常用的HDFS操作
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758650.html
Copyright © 2011-2022 走看看