zoukankan      html  css  js  c++  java
  • 51nod-1686 第K大区间(二分+尺取法)

    题目链接:

    第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

    题意:

    思路:

    先把数组都离散为[1,n]的数,注意相等的;
    再二分答案t,check区间众数大于等于t的区间有多少个;(可以设区间众数大于等于t的区间为合法区间)
    check的时候采用尺取法,按顺序枚举每个区间的左端点i,然后找到区间右端点的最小值;以这个左端点为合法区间的方案数为n-(r-1);
    复杂度为O(nlogn)

    AC代码:

    //#include <bits/stdc++.h>
    #include <vector>
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef long long LL;
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e10;
    const int N=1e5+15;
    
    int n,k;
    int a[N],flag[N];
    struct node
    {
        int a,id,ans;
    }po[N];
    int cmp(node x,node y)
    {
        if(x.a==y.a)return x.id<y.id;
        return x.a<y.a;
    }
    int cmp1(node x,node y)
    {
        return x.id<y.id;
    }
    
    int check(int x)
    {
        mst(flag,0);
        LL ans=0;
        int num=0;
        int r=0;
        Riep(n)
        {
            while(1)
            {
                int pos=po[r].ans;
              if(pos!=-1) if(flag[pos]>=x||r>n)break;
                r++;
                pos=po[r].ans;
                flag[pos]++;
            }
            ans=ans+n-(r-1);
            flag[po[i].ans]--;
        }
        if(ans>=k)return 1;
        return 0;
    }
    
    int main()
    {
        read(n);read(k);
        Riep(n)read(po[i].a),po[i].id=i;
        sort(po+1,po+n+1,cmp);
        po[0].ans=po[0].a=-1;
        Riep(n)
        {
            if(po[i].a!=po[i-1].a)po[i].ans=i;
            else po[i].ans=po[i-1].ans;
        }
        sort(po+1,po+n+1,cmp1);
    
        int l=1,r=n;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))l=mid+1;
            else r=mid-1;
        }
        print(l-1);
        return 0;
    }
  • 相关阅读:
    datadog数据json格式转换prometheus文本格式
    clickhouse聚合
    iOS面试
    程序员如何快速准备面试中的算法
    李刚OC语言疯狂讲义笔记
    传智播客内部 学习网站+书籍分享
    iOS-多线程总结笔记
    iOS-简化单例模式(定义成宏 以后通用)
    iOS-单例模式(懒汉式和饿汉式)和GCD实现
    iOS-队列组
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5551277.html
Copyright © 2011-2022 走看看