LYDSY模拟赛day3 平均数

【 问题描述】
有一天, 小 A 得到了一个长度为 n 的序列。
他把这个序列的所有连续子序列都列了出来, 并对每一个子序列
都求了其平均值, 然后他把这些平均值写在纸上, 并对它们进行排序,
最后他报出了第 k 小的平均值。
你要做的就是模仿他的过程。
【 输入格式】
第一行两个整数 n,k, 意义如题中所述。
第二行 n 个正整数, 即为小 A 得到的序列。
【 输出格式】
一行一个实数, 表示第 k 小的平均值, 保留到小数点后 4 位。
【 样例输入输出】

ave.in ave.out
6 10
3 5 4 6 1 2
3.6667

【 数据范围与约定】
对于 40%的数据, n≤1000
对于 100%的数据, n≤100000, k≤n*(n+1)/2, 序列中的数≤109

/*
第 k 大不易直接求, 我们想到二分, 则原问题转变为求区间平均
值小于 x 的区间数量。 考虑把序列中的每个数减去 x, 则我们只需求
区间和小于 0 的区间数量。 我们对这个序列求前缀和, 则区间[l,r]和
小于 0 当且仅当 Sl-1> Sr , 答案即为前缀和序列 S 的逆序对数量, 使
用经典的归并排序即可解决, 时间复杂度 O(nlog2n)。
*/
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef double db;
typedef long long ll;
const int N=100010;
const db eps=1e-6;
db b[N],c[N];
int a[N];
ll ans=0;
int n;
void solve(int l,int r){
    if(l==r) return;
    int M=l+r>>1;
    solve(l,M);solve(M+1,r);
    int i=l,j=M+1,k=l-1;
    while(i<=M&&j<=r){
        if(b[i]<b[j]) c[++k]=b[i++];
        else c[++k]=b[j++],ans+=M-i+1;
    }
    while(i<=M) c[++k]=b[i++];
    while(j<=r) c[++k]=b[j++];
    for(i=l;i<=r;i++) b[i]=c[i];
}
ll calc(db x){
    b[0]=0;
    for(int i=1;i<=n;i++) b[i]=a[i]-x+b[i-1];
    ans=0;
    solve(0,n);
    return ans;
}
int main(){
    freopen("ave.in","r",stdin);
    freopen("ave.out","w",stdout);
    int mx=0,i;
    db lb,rb,mid;
    ll x;
    scanf("%d %lld",&n,&x);
    for(i=1;i<=n;i++) scanf("%d",&a[i]),mx=max(mx,a[i]);
    lb=0;rb=mx;
    while(rb-lb>eps){
        mid=(lb+rb)/2;
        if(calc(mid)<x) lb=mid;
        else rb=mid;
    }
    printf("%.4lf\n",lb);
    return 0;
}
时间: 2024-10-13 22:23:46

LYDSY模拟赛day3 平均数的相关文章

LYDSY模拟赛day3 序列

NOIP不考可持久,弃坑

LYDSY模拟赛day1 Walk

/* 依旧考虑新增 2^20 个点. i 只需要向 i 去掉某一位的 1 的点连边. 这样一来图的边数就被压缩到了 20 · 2^20 + 2n + m,然后 BFS 求出 1 到每个点的最短路即可. 时间复杂度 O(20 · 2^20 + n + m) */ #include<cstdio> const int N=1300000,M=700010; int n,m,i,x,y,cnt,g0[N],g1[N],v[M],nxt[M],ed,h,t,q[N],d[N]; void add(in

LYDSY模拟赛day2 Dash Speed

/* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; const int N=70010,M=N*20; int n,m,i,g[N],v[N<<1],nxt[N<<1],ed,cur,ans[N]; int size[N],f[N],d[N],son[N],top[N]; int fa[N],dep[N],A[N],B[N]; int G[262150],V[M],W[M],N

LYDSY模拟赛day2 Market

/* orz claris,这个题的解法非常巧妙,首先是时间问题,其实这个问题只要离线处理一下就可以了,把物品和询问都按照时间排序,然后看一下能不能满足.然后,因为容量<=10^9,显然是不可能开一个这么大的数组,而且这么大一个容量,价值又很小,我们可以考虑用二分解决 对每个询问二分答案,需要判定用容量为 M 的背包是否可 以装下 mid 的价值. 设 fi 表示装了 i 价值所需的最小容量,gi 表示 min(fi,fi+1,fi+2,……). 那么只需要检查 gmid 是否不超过 M 即可.

LYDSY模拟赛day2 Divisors

/* 注意分解质因数,如果i是,那么n/i也是,这样就可以解决分解质因数的时间问题了 当 k ≥ 1 时,只有这些数的约数才会对答案产生贡献. 求出 m 个数的所有不超过 n 的约数,去重后统计即可. 求出 k = 1 到 m 的所有答案后,剩下的数字个数就是 k = 0 的答案. 时间复杂度 O(m2√a) */ #include<cstdio> #include<algorithm> const int N=205; int n,m,i,a[N],cnt,b[1000000],

LYDSY模拟赛 escape

Description 给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2).在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下你最少要走多少步才可以回到目标点.注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(

NOI模拟赛Day3

终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ---------------------------------------------------- T1 题意:huffman树的过程,只不过不贪心取,随机取,问最后的期望结果 好像很多人做对的样子.. 发现其实结果和每个数是什么是没有关系的,而且每个数对答案的期望贡献是相同的 于是我们可以

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=