zoukankan      html  css  js  c++  java
  • 51nod 平均数(二分+树状数组)

    题目链接:

    平均数

    基准时间限制: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


    题意:


    思路:

    二分答案,假设平均数为t,那么(sum[i]-sum[j])/(i-j)>=t;变形得sum[i]-t*i>=sum[j]-t*j(0<=j<i);
    temp[i]=sum[i]-t*i;
    即对于每个temp[i]统计有多少个temp[j]<=temp[i],每个i的和再和k比较就可以对t的取值进行二分了;




    AC代码:

    #include <bits/stdc++.h>
    /*
    #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;
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=1e5+4;
    int n,num[N];
    LL k;
    double sum[N],a[N],temp[N];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x)
    {
        while(x<=n)
        {
            num[x]++;
            x+=lowbit(x);
        }
    }
    int query(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=num[x];
            x-=lowbit(x);
        }
        return ans;
    }
    struct node
    {
        double temp;
        int id,pos;
    }po[N];
    int cmp1(node x,node y)
    {
        if(x.temp==y.temp)x.id<y.id;
        return x.temp<y.temp;
    }
    int cmp2(node x,node y)
    {
        return x.id<y.id;
    }
    int check(double x)
    {
        mst(num,0);
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            po[i].temp=sum[i]-x*i;
            po[i].id=i;
        }
        sort(po+1,po+n+1,cmp1);
        for(int i=1;i<=n;i++)po[i].pos=i;//离散化
        sort(po+1,po+n+1,cmp2);
        for(int i=1;i<=n;i++)
        {
            if(po[i].temp>=0)ans++;//还有0的情况;
            ans=ans+(LL)query(po[i].pos);
            update(po[i].pos);
        }
        if(ans>=k)return 1;
        return 0;
    }
    int main()
    {
          cin>>n>>k;
          Riep(n)
          {
              scanf("%lf",&a[i]);
              sum[i]=sum[i-1]+a[i];
          }
          double l=1,r=100000;
          while(abs(r-l)>=0.0001)
          {
              double mid=(l+r)/2;
              if(check(mid))l=mid;
              else r=mid;
          }
          printf("%.8lf
    ",l);
        return 0;
    }


  • 相关阅读:
    理解WebKit和Chromium: Chromium的多线程机制
    java.lang.IllegalStateException: Web app root system property already set to different value
    MySQL 深入剖析 char varchar 类型,有了VARCHAR,为什么还要有CHAR?
    Ubuntu包管理命令大全,包括apt命令和dpkg命令
    GHashTable不能以字符串作为key,可以使用data list来代替
    LFS全过程历险
    忘记了root密码怎么办?
    ArchLinux安装几天的经验总结、bug修正和软件配置
    mplayer加载srt字幕乱码,或是下划线等问题解决
    从串口登录Linux主机
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5543945.html
Copyright © 2011-2022 走看看