zoukankan      html  css  js  c++  java
  • 联赛模拟测试5 平均数 二分答案+逆序对

    题目描述

    分析

    之前做过类似的两道题,一道是区间和的(k)小值,一道是众数的(k)小值

    那两道统计的东西都有单调性,可以用两个指针维护,(O(n))计算

    但是平均数没有单调性,不能用两个指针去扫

    但是这道题的数据范围是 (10^5),时间限制是(2.5s)

    统计答案时还可以再套一个(log)

    如果当前枚举的平均值是(mid)的话

    我们只需要找出所有(frac{sum[j]-sum[i]}{j-i} leq mid)的数对即可

    我们把分母乘过去,就变成了(sum[i]-mid imes i geq sum[j]-mid imes j)

    可以看成区间求逆序对

    用树状数组做需要离散化,用归并排序比较方便

    代码

    
    
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    typedef double db;
    const int maxn=1e6+5;
    const db eps=1e-6;
    int n,a[maxn];
    long long sum[maxn],m,js;
    db b[maxn],c[maxn];
    void msort(int l,int r){
    	if(l==r) return;
    	int mids=(l+r)>>1;
    	msort(l,mids);
    	msort(mids+1,r);
    	int now=l,t=l-1;
    	for(int i=mids+1;i<=r;i++){
    		while(b[now]<b[i] && now<=mids){
    			c[++t]=b[now++];
    		}
    		js+=mids-now+1;
    		c[++t]=b[i];
    	}
    	while(now<=mids) c[++t]=b[now++];
    	for(int i=l;i<=r;i++) b[i]=c[i];
    }
    bool jud(db mids){
    	for(int i=0;i<=n;i++){
    		b[i]=sum[i]-i*mids;
    	}
    	js=0;
    	msort(0,n);
    	if(js>=m) return 1;
    	else return 0;
    }
    int main(){
    	freopen("ave.in","r",stdin);
    	freopen("ave.out","w",stdout);
    	scanf("%d%lld",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=n;i++){
    		sum[i]=sum[i-1]+a[i];
    	}
    	double l=-1e9,r=1e9,mids;
    	while(r-l>eps){
    		mids=(l+r)/2.0;
    		if(jud(mids)) r=mids;
    		else l=mids;
    	}
    	printf("%.4f
    ",mids);
    	return 0;
    }
    
    
  • 相关阅读:
    转 IDEA 解决代码提示功能消失
    模态框居中显示
    DetachedCriteria和Criteria的使用方法
    struts2配置文件详解
    springMVC上传图片
    在linux下运行mongodb
    webSocket客服在线交谈
    接口自动化
    easyui input文本框清除值
    Spring总结
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13720906.html
Copyright © 2011-2022 走看看