• 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
    一个数表示答案。
    Input示例
    4 2
    1 2 3 2
    Output示例
    2



    //首先,考虑区间的值的性质,如果区间的值为 x ,那么,区间无论怎么左右扩展,区间的值必然大于等于 x 。
    那么,计算区间的值大于等于 x ,可以用尺取在 O(n) 时间算出,显然,这是有单调性的,二分即可
     1 # include <cstdio>
     2 # include <cstring>
     3 # include <cstdlib>
     4 # include <iostream>
     5 # include <vector>
     6 # include <queue>
     7 # include <stack>
     8 # include <map>
     9 # include <bitset>
    10 # include <sstream>
    11 # include <set>
    12 # include <cmath>
    13 # include <algorithm>
    14 # pragma  comment(linker,"/STACK:102400000,102400000")
    15 using namespace std;
    16 # define LL          long long
    17 # define pr          pair
    18 # define mkp         make_pair
    19 # define lowbit(x)   ((x)&(-x))
    20 # define PI          acos(-1.0)
    21 # define INF         0x3f3f3f3f3f3f3f3f
    22 # define eps         1e-8
    23 # define MOD         1000000007
    24 
    25 inline int scan() {
    26     int x=0,f=1; char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    29     return x*f;
    30 }
    31 inline void Out(int a) {
    32     if(a<0) {putchar('-'); a=-a;}
    33     if(a>=10) Out(a/10);
    34     putchar(a%10+'0');
    35 }
    36 # define MX 100005
    37 /**************************/
    38 
    39 int n,k;
    40 int a[MX];
    41 int b[MX];
    42 int num[MX];
    43 
    44 bool check(int x)
    45 {
    46     memset(num,0,sizeof(num));
    47     int l=1,r=1,flag=0;
    48     LL tot=0;
    49     while (r<=n+1)
    50     {
    51         if (!flag)
    52         {
    53             if (r==n+1) break;
    54             num[a[r]]++;
    55             if (num[a[r]]>=x) flag=r;
    56             r++;
    57         }
    58         else
    59         {
    60             while (flag)
    61             {
    62                 tot += n-r+2;
    63                 num[a[l]]--;
    64                 if (num[a[flag]]<x) flag=0;
    65                 l++;
    66             }
    67         }
    68     }
    69     if (tot>=k) return 1;
    70     return 0;
    71 }
    72 
    73 int main()
    74 {
    75     scanf("%d%d",&n,&k);
    76     for (int i=1;i<=n;i++)
    77     {
    78         scanf("%d",&a[i]);
    79         b[i] = a[i];
    80     }
    81     sort(b+1,b+1+n);
    82     for (int i=1;i<=n;i++)
    83         a[i] = lower_bound(b+1,b+1+n,a[i])-b;
    84 
    85     int l=1, r=n;
    86     int ans;
    87     while (l<=r)
    88     {
    89         int mid = (l+r)>>1;
    90         if (check(mid)) ans=mid,l=mid+1;
    91         else r=mid-1;
    92     }
    93     printf("%d
    ",ans);
    94     return 0;
    95 }
    View Code
     
  • 相关阅读:
    C++中的explicitkeyword
    SQLite数据库查看工具(免费)
    C Tricks(十九)—— 求以任意数为底的对数
    分治法(divide & conquer)与动态规划(dynamic programming)应用举例
    分治法(divide & conquer)与动态规划(dynamic programming)应用举例
    C++组合数(combination)的实现
    C++组合数(combination)的实现
    算法求解方法与思路的总结
    算法求解方法与思路的总结
    使用 STL 辅助解决算法问题
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7516170.html
Copyright © 2020-2023  润新知