51Nod——T 1686 第K大区间

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

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

定义一个区间的值为其众数出现的次数
现给出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



二分区间的值 x (logn)
枚举一个右端点,记录[l,r]之间每个数的出现个数(离散化,map统计)
如果一个数在[l,r]中的出现个数>=x,则 当 r 属于[r+1,n] 中时,同样满足
满足时,不断缩小l,判断每个区间的情况 (o(n))
nlogn
 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 inline void read(int &x)
 6 {
 7     x=0; register char ch=getchar();
 8     for(; ch>'9'||ch<'0'; ) ch=getchar();
 9     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
10 }
11 
12 const int N(100005);
13 int n,k,b[N];
14 
15 struct Node {
16     int num,id;
17     bool operator < (const Node&x)const
18     {
19         return num<x.num;
20     }
21 }a[N];
22 
23 int L,R,Mid,ans,cnt[N];
24 inline bool check(int x)
25 {
26     memset(cnt,0,sizeof(cnt));
27     int l=1,r=1,ret=0;
28     for(; r<=n; ++r)
29     {
30         cnt[b[r]]++;
31         if(cnt[b[r]]>=x)
32         {
33             ret+=n-r+1;
34             cnt[b[l++]]--;
35             for(; cnt[b[r]]>=x&&l<r; )
36             {
37                 ret+=n-r+1;
38                 cnt[b[l++]]--;
39             }
40         }
41         if(ret>=k) return 1;
42     }
43     return 0;
44 }
45 
46 int Presist()
47 {
48     read(n),read(k);
49     for(int i=1; i<=n; ++i)    read(a[i].num),a[i].id=i;
50     std::sort(a+1,a+n+1);
51     for(int i=1; i<=n; ++i)
52         b[a[i].id]=(a[i].num!=a[i-1].num)?++a[0].id:a[0].id;
53     for(L=0,R=n; L<=R; )
54     {
55         Mid=L+R>>1;
56         if(check(Mid))
57         {
58             ans=Mid;
59             L=Mid+1;
60         }
61         else R=Mid-1;
62     }
63     printf("%d",ans);
64     return 0;
65 }
66 
67 int Aptal=Presist();
68 int main(int argc,char**argv){;}

 

posted @ 2017-10-15 16:02  Aptal丶  阅读(159)  评论(0编辑  收藏  举报