51nod 1711 平均数(二分 + 树状数组好题)

简介: 51nod 1711 平均数(二分 + 树状数组好题)

LYK有一个长度为n的序列a。

他最近在研究平均数。

他甚至想知道所有区间的平均数,但是区间数目实在太多了。

为了方便起见,你只要告诉他所有区间(n*(n+1)/2个区间)中第k大的平均数就行了。

输入

第一行两个数n,k(1<=n<=100000,1<=k<=n*(n+1)/2)。

接下来一行n个数表示LYK的区间(1<=ai<=100000)。

输出

一行表示第k大的平均数,误差不超过1e-4就算正确。

输入样例

5 3

1 2 3 4 5

输出样例

4.000


首先看题目求区间第k大,首先想到分第k大的平均数x。问题转化为如何快速求任意区间的平均数大于x的个数,先求求前缀和,则可以表示为(sum[r] - sum[l-1])/(r - l +1) > x 的区间个数,转化一下即为sum[r] - r*x > sum[l-1] - (l-1) * x;即形成一个新的数组sum[i]- i * x,求满足条件的区间有多少个,离散化一下,用树状数组统计一下就行。

注意:i从0开始,sum[0] = 0;也要算进去,不然会把0-1的区间漏掉。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
typedef long double ld;
typedef long long ll;
ll n, k;
const ld eps = 1e-6;
ld sum[maxn];
ld a[maxn], b[maxn];
ll tmp[maxn]; 
ll c[maxn];
int lowbit(int x) {
  return x & (-x);
}
void add(int x) {
  for (int i = x; i <= n + 1; i += lowbit(i)) c[i]++;
}
ll Sum(int x) {
  ll ans = 0;
  for (int i = x; i >= 1; i -= lowbit(i)) ans += c[i];
  return ans;
}
ll check(ld mid) {
  memset(c, 0, sizeof(c));
  for (int i = 0; i <= n; i++) {
    a[i] = b[i] = sum[i] - i * mid;
  }
  sort (a, a + n + 1);
  int m = unique(a, a + n + 1) - a;
  for (int i = 0; i <= n; i++) {
    tmp[i] = lower_bound(a, a + m + 1, b[i]) - a + 1;
  }
  long long ans = 0;
  for (int i = 0; i <= n; i++) {
    ans += Sum(tmp[i]);
    add(tmp[i]);
  }
  return ans;
}
int main() {
  int x;
  scanf("%lld%lld", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &x);
    sum[i] = sum[i - 1] + x;
  }
  ld l = 1.0, r = 100000.0;
  while (r - l >= eps) {
    ld mid = (l + r) / 2.0;
    if (check(mid) >= k) {
      l = mid;
    } else {
      r = mid;
    }
  }
  printf("%.4Lf", (r + l) / 2.0);
  return 0;
}
相关文章
|
6月前
D - 11(逆元好题)
D - 11(逆元好题)
|
算法
数星星(树状数组模板题)
数星星(树状数组模板题)
59 0
|
算法
【leedcode】0004. 两个有序数组的中位数
【leedcode】0004. 两个有序数组的中位数
77 0
|
人工智能
线段树水题
Problem Description 很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
113 0
|
机器学习/深度学习 人工智能 BI
“玲珑杯”ACM比赛 Round #19题解&源码【A,规律,B,二分,C,牛顿迭代法,D,平衡树,E,概率dp】
A -- simple math problem Time Limit:2s Memory Limit:128MByte Submissions:1599Solved:270 SAMPLE INPUT 5 20 1314 SAMPLE OUTPU...
940 0
BZOJ 1012: [JSOI2008]最大数maxnumber【线段树单点更新求最值,单调队列,多解】
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 10374  Solved: 4535[Submit][Status][Discuss] Description   现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。
1260 0
|
Windows Perl
Codeforces 626G Raffles(贪心+线段树)
G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input output:standard output Johnny is at a carnival which has n raffles.
1284 0
|
人工智能
POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)
Brainman Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10575   Accepted: 5489 Description BackgroundRaymond Babbitt drives his brother Charlie mad.
1260 0
|
Java
HDU 1754 I Hate It(线段树之单点更新,区间最值)
I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 70863    Accepted Submission(s): 27424 Problem Description 很多学校流行一种比较的习惯。
1100 0