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;
}


 

 

posted @ 2016-04-05 16:41  zhangxianlong  阅读(95)  评论(0编辑  收藏  举报