• 51nod 平均数(马拉松14)


    alpq654321 (命题人)
     
    基准时间限制:4 秒 空间限制:131072 KB 分值: 80
    LYK有一个长度为n的序列a。
    他最近在研究平均数。
    他甚至想知道所有区间的平均数,但是区间数目实在太多了。
    为了方便起见,你只要告诉他所有区间(n*(n+1)/2个区间)中第k大的平均数就行了。
    Input
    第一行两个数n,k(1<=n<=100000,1<=k<=n*(n+1)/2)。
    接下来一行n个数表示LYK的区间(1<=ai<=100000)。
    Output
    一行表示第k大的平均数,误差不超过1e-4就算正确。
    Input示例
    5 3
    1 2 3 4 5
    Output示例
    4.000

    /*
    51nod 平均数
    
    题目:给你n个数,可以知道总共可以组成 (n+1)*n/2 个区间,那么请问这些区间中第k大的平均值
    最开始是一点思路都没有,后来看到一个有点相似的题目,发现我们可以吧问题转换成 平均值大于
    x的区间有多少个
    
    这样就可以通过枚举答案,然后通过判断解决。用f[i]表示前i个数的和,那么:
    Ave = (f[r]-f[l])/(r-l)    所以Ave >= x  --->  f[r]-rx >= f[l]-lx即前面出现的比当前值小的个数
    但是发现 f[r]-rx 可以达到-10^10,而且是浮点型。于是又纠结了很久,一开始也想到了离散化(但总觉得会超时Orz)
    结果发现的确是自己想太多,利用sort,每次查找当前值是第几个,然后利用树状数组维护即可。
    
    hhh 2016/05/28 16:22:06
    */
    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    #include <functional>
    #include <map>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef long long ll;
    using namespace std;
    const int maxn = 101010;
    const double PI = 3.1415926;
    const double eps = 1e-6;
    double a[maxn];
    ll s[maxn];
    double f[maxn];
    double g[maxn];
    int n;
    ll k;
    
    void add(int x,int val)
    {
        while(x <= 100000)
        {
            s[x] += val;
            x += (x&(-x));
        }
    }
    
    ll sum(int pos)
    {
        ll ans = 0;
        while(pos > 0)
        {
            ans += s[pos];
            pos -= (pos&(-pos));
        }
        return ans;
    }
    
    bool cal(double x)
    {
        memset(s,0,sizeof(s));
        f[0] = 0;
        for(int i = 1; i <= n; i++)
            f[i] = f[i-1] + a[i];
        ll num = 0;
        for(int i = 1; i <= n; i++)
        {
            f[i] -= (double)i*x;
            g[i] = f[i];
            if(f[i] > 0)
                num ++;
        }
        sort(g+1,g+n+1);
    
    //    for(int i = 1;i <= n;i++)
    //        cout << g[i] <<" ";
    //    cout << endl;
        for(int i = 1; i <= n; i++)
        {
            int pla = lower_bound(g+1,g+n+1,f[i])-g;
            num += sum(pla);
            add(pla,1);
        }
        if(num >= k)
            return true;
        else
            return false;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%d",&n);
        scanf("%lld",&k);
        double Max = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf",&a[i]);
            Max = max(a[i],Max);
        }
        double l = 0;
        double r = Max;
        while( r - l > eps)
        {
            double mid = (l+r)/2;
            if(cal(mid))
                l = mid;
            else
                r = mid-eps;
        }
        printf("%f
    ",l);
        return 0;
    }
    

      

  • 相关阅读:
    解决编程开发时候文件命名的苦恼(规范代码 提高可读性)
    react的this.setState没有触发render
    动态修改JS对象的值及React setState
    Antd Select组件结合使用出现must set key for <rc-animate> children问题
    antd Select进阶功能 动态更新、函数防抖
    前端性能优化之重排和重绘
    ES5 map循环一大坑:循环遍历竟然出现逗号!
    Monent.js:强大的日期处理类库
    Docker概览
    Spring boot 集成hessian
  • 原文地址:https://www.cnblogs.com/Przz/p/5547929.html
Copyright © 2020-2023  润新知