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

    一、题意

      这题刚看到想了5分钟左右没有啥思路(在上某大佬的某节课发现并不能听懂也似乎没啥实践指导意义,遂怒写一题)。于是查了下看看对方的代码,正准备进行:看到半懂,复刻,重写若干遍这种流程的时候,发现其思路意外的简单。

      题意复制如下:
    定义一个区间的值为其众数出现的次数
    现给出n个数,求将所有区间的值排序后,第K大的值为多少。
    第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 
    第二行n个数,0<=每个数<2^31

    二、题解

      用尺取法统计大于某个值得区间的个数,之后可以在ON的时间内搞定检查,因为必然具有单调性,于是可以进行二分。

    三、代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long 
    #define veci vector<int>
    const ll MAXN=100233;
    
    
    ll arr[MAXN];
    ll numbers[MAXN];
    ll n,k;
    int vis[MAXN];
    inline int checkPos(int i)
    {
        return lower_bound(numbers,numbers+n,arr[i])-numbers;
    }
    ll check(int limit)
    {
        ll ans=0;
        memset(vis,0,sizeof(vis));
        int spos=-1;
        for(int i=0;i<n;++i)
        {
            vis[arr[i]]++;
            while(vis[arr[i]]>=limit)
            {
                ans+=n-i;
                spos++;
                vis[arr[spos]]--;
            }
        }return ans;
    }
    int search(int a,int b)
    {
        if(a==b-1)return a;
        int mid=(a+b)/2;
        if(check(mid)<k)search(a,mid);
        else search(mid,b);
    }
    void init()
    {
        for(int i=0;i<n;++i)
        {
            cin>>arr[i];
            numbers[i]=arr[i];
        }sort(numbers,numbers+n);
        for(int i=0;i<n;++i)
        {
            arr[i]=checkPos(i);
        }
        cout<<search(1,n);
        
    }
    
    int main()
    {
        cin.sync_with_stdio(false);
        cin>>n>>k;init();
        
        
        return 0;
    }
  • 相关阅读:
    [转]C#中抽象类和接口的区别
    [转]OO设计原则总结
    [转]MVC3快速搭建Web应用(三)实例篇
    原生内存(堆外内存)
    使用SAX解析XML实例根据属性查找
    Cannot forward after response has been committed问题解决及分析
    dubbo服务化实施整理
    bean:write 标签不能显示出 换行符的解决方案
    Dubbo原理解析监控
    thread之1:java与线程
  • 原文地址:https://www.cnblogs.com/rikka/p/7879604.html
Copyright © 2011-2022 走看看