zoukankan      html  css  js  c++  java
  • 1686 第K大区间

    时间限制:1 秒 空间限制:131072 KB
     

    定义一个区间的值为其众数出现的次数
    现给出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
    思路:二分答案t,统计众数出现次数大于等于t的区间有多少个。
    枚举右端点R,计算左端点L最大为多少,使得区间[L,R]的值大于等于t,对于每个R他对答案贡献为L。
    通过线性扫一遍找出每一个数的前面第t-1个与他相同的数字,记其位置为b[i],若不存在则为0。
    若R增加,则[L,R+1]的值也必定大于等于t,所以新的L=max(L,b[R+1]),这样就可以找出每一个R对应的L,O(n)计算出答案。
    总复杂度O(nlogn)
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<queue>
      6 #include<stack>
      7 #include<map>
      8 #include<math.h>
      9 using namespace std;
     10 typedef long long LL;
     11 int id[100005];
     12 int cnt[100005];
     13 int cp[100005];
     14 int str[100005];
     15 LL tt[100005];
     16 typedef struct pp
     17 {
     18     LL x;
     19     int id;
     20 } ss;
     21 ss ans[100005];
     22 LL check(int mid);
     23 bool cmp(pp n,pp m)
     24 {
     25     return n.x<m.x;
     26 }
     27 LL n,m;
     28 int main(void)
     29 {
     30     int i,j,k;
     31     while(scanf("%lld %lld",&n,&m)!=EOF)
     32     {
     33         memset(cnt,0,sizeof(cnt));
     34         for(i=1; i<=n; i++)
     35         {
     36             scanf("%lld",&ans[i].x);
     37             ans[i].id=i;
     38         }
     39         LL nn=ans[1].x;
     40         int mm=1;
     41         sort(ans+1,ans+n+1,cmp);
     42         for(i=1; i<=n; i++)
     43         {
     44             if(ans[i].x!=nn)
     45             {
     46                 mm++;
     47                 nn=ans[i].x;
     48             }
     49             tt[ans[i].id]=mm;
     50         }
     51         for(i=1;i<=n;i++)
     52         {
     53             ans[i].x=tt[i];
     54         }
     55         int maxx=0;
     56         for(i=1; i<=n; i++)
     57         {
     58             cnt[ans[i].x]++;
     59             if(maxx<cnt[ans[i].x])
     60             {
     61                 maxx=cnt[ans[i].x];
     62             }
     63         }
     64         int l=1;
     65         int ask=1;
     66         int r=maxx;
     67         while(l<=r)
     68         {
     69             int mid=(l+r)/2;
     70             LL ak=check(mid);
     71             LL cnt1=(n)*(n-1)/2;
     72             if(ak>=m)
     73             {  ask=mid;
     74                l=mid+1;
     75             }
     76             else
     77             { r=mid-1;
     78 
     79             }
     80         }printf("%d
    ",ask);
     81     }
     82     return 0;
     83 }
     84 LL check(int mid)
     85 {
     86     int i,j,k;
     87     LL sum=0;
     88     if(mid==1)
     89         return n*(n-1)/2;
     90     else
     91     {
     92         memset(id,0,sizeof(id));
     93         memset(cnt,0,sizeof(cnt));
     94         memset(str,0,sizeof(str));
     95         cnt[ans[1].x]++;str[ans[1].x]=1;id[1]=0;
     96         for(i=2; i<=n; i++)
     97         {
     98             cnt[ans[i].x]++;
     99             if(cnt[ans[i].x]==1)
    100             {
    101                 str[ans[i].x]=i;
    102                 id[i]=0;
    103             }
    104             else if(cnt[ans[i].x]==mid)
    105             {
    106                 id[i]=str[ans[i].x];
    107             }
    108             else if(cnt[ans[i].x]<mid)
    109             {
    110                 id[i]=0;
    111             }
    112             else  if(cnt[ans[i].x]>mid)
    113             {
    114                 while(cnt[ans[i].x]>mid)
    115                 {
    116                     str[ans[i].x]++;
    117                     if(ans[str[ans[i].x]].x==ans[i].x)
    118                     {
    119                         cnt[ans[i].x]--;
    120                         break;
    121                     }
    122                 }id[i]=str[ans[i].x];
    123             }
    124         }
    125         int L=0;
    126         LL sum=0;
    127         for(i=1; i<=n; i++)
    128         {
    129             L=max(L,id[i]);
    130             sum+=L;
    131 
    132         }printf("
    ");
    133         return sum;
    134     }
    135 }
    油!油!you@
  • 相关阅读:
    return
    debug_backtrace final catch
    Exponential Backoff
    2014 MapReduce
    Extract, Transform, Load
    Factorization of a 768-bit RSA modulus
    奇偶校验 汉明码 如果一条信息中包含更多用于纠错的位,且通过妥善安排这些纠错位使得不同的出错位产生不同的错误结果,那么我们就可以找出出错位了。 crc CRC 循环冗余校验
    An Explanation of the Deflate Algorithm
    通过极限手续定义正数的无理指数方幂
    算术根的存在唯一性
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5472343.html
Copyright © 2011-2022 走看看