zoukankan      html  css  js  c++  java
  • 51nod 1686 第k大区间

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注

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

    众数(统计学/数学名词)_百度百科 

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

    一个数表示答案。

     

     

    首先想到二分答案,然后在o(n)或者o(nlogn)的复杂度里面判断比二分的X大的有多少个,

    这道题学到的重要的思维是枚举区间右端点R,然后动态更新最大的L,那么就可以判断有L个区间符合,这样统计就不会漏掉。这里我的做法比较笨,复杂度应该是o(nlogn^2),用了map瞎搞,明显不是一个好的解法,主要学习枚举R的思维方式。继续努力吧蒟蒻。。。

     

     

    #include <iostream>
    #include <unordered_map>
    #include <vector>
    #include <cstdio>
    using namespace std;
    int n;
    long long k;
    unordered_map<int,int> hashs;
    vector<int> v[100005];
    const int maxn=100005;
    struct po{
    int r,l;
    };
    
    int arr[maxn];
    int cnt[maxn];
    long long cal(int x){
        long long ret=0;
        vector<po> pa;
        for(int i=0;i<n;i++){
            if(cnt[i]>=x){
                int l=v[hashs[arr[i]]][cnt[i]-x];
                po p;
                p.l=l;
                p.r=i;
                pa.push_back(p);
            }
        }
        int add=0;
        for(int i=0,j=0;i<n;i++){
            if(j<pa.size()){
                if(j+1<pa.size()&&i>=pa[j+1].r){
                    j++;
                }
                if(i>=pa[j].r){
                    add=max(add,pa[j].l+1);
                    ret+=add;
                }
    
            }
        }
        return ret;
    }
    
    int bs(int a,int b,long long val){
        int low=a,high=b;
        int ret=0;
        while(low<=high){
            int mid=(low+high)/2;
            ret=mid;
            long long x=cal(mid);
            if(x==val)
                break;
            else if(x<val){
                high=mid-1;
            }
            else{
                low=mid+1;
            }
        }
        long long x1=cal(ret);
        if(x1==val){
            return ret;
        }
        else if(x1<val){
            return ret-1;
        }
        else if(x1>val){
            return ret;
        }
    }
    
    int main()
    {
        cin>>n>>k;
        for(int i=0;i<n;i++){
            scanf("%d",&arr[i]);
            hashs[arr[i]]++;
            cnt[i]=hashs[arr[i]];
        }
        unordered_map<int,int>::iterator it=hashs.begin();
        for(int i=0;it!=hashs.end();i++,it++){
            it->second=i;
        }
        for(int i=0;i<n;i++){
            v[hashs[arr[i]]].push_back(i);
        }
        cout<<bs(1,n,k)<<endl;
        return 0;
    }
    


     

  • 相关阅读:
    CSS浏览器兼容问题大全
    JavaScript游戏之飞机接子弹
    Html5小游戏之变大的小球
    JavaScript游戏之小型打飞机
    JavaScript游戏之是男人就飞10000米
    JavaScript无聊打地鼠
    JavaScript游戏之优化篇
    前端开发的开始基于OO的Ajax类
    JavaScript游戏之仿劲舞团(简陋版)
    仿JQuery的show与hide动画函数
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672589.html
Copyright © 2011-2022 走看看