• 【JZOJ4869】【NOIP2016提高A组集训第9场11.7】平均数


    题目描述

    这里写图片描述

    数据范围

    这里写图片描述

    解法

    二分答案。
    对于一个答案mid,要求出区间平均数小于mid的个数ans。
    给所有数减去mid,那么问题转化为求出所有区间和为负数的个数。
    对于一个区间[l,r],如果sum[r]-sum[l-1]<0,那么这个区间和就为负数。
    算出前缀和后,利用归并排序对逆序对计数。
    ans即为这个计数器的值。

    代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const char* fin="ave.in";
    const char* fout="ave.out";
    const int inf=0x7fffffff;
    const int maxn=100007;
    int n,m,i,j,k;
    double l,r,mid;
    ll ans;
    int a[maxn];
    double sum[maxn],xsum[maxn];
    void mergesort(int l,int r){
        int i,j,k,mid=(l+r)/2;
        if (l==r) return ;
        mergesort(l,mid);
        mergesort(mid+1,r);
        i=l;
        j=mid+1;
        k=l;
        while (i<=mid && j<=r){
            if (sum[i]>=sum[j]){
                xsum[k++]=sum[j++];
                ans+=mid-i+1;
            }else xsum[k++]=sum[i++];
        }
        while (i<=mid) xsum[k++]=sum[i++];
        while (j<=r) xsum[k++]=sum[j++];
        for (i=l;i<=r;i++) sum[i]=xsum[i];
    }
    bool judge(double v){
        sum[0]=0;
        for (i=1;i<=n;i++){
            sum[i]=sum[i-1]+a[i]-v;
        }
        ans=0;
        mergesort(0,n);
        return ans>=m;
    }
    int main(){
        freopen(fin,"r",stdin);
        freopen(fout,"w",stdout);
        scanf("%d%d",&n,&m);
        for (i=1;i<=n;i++) scanf("%d",&a[i]);
        l=0;
        r=10e9;
        while (r-l>10e-6){
            mid=(l+r)/2;
            if (judge(mid)) r=mid;
            else l=mid;
        }
        printf("%.4lf",l);
        return 0;
    }

    启发

    又一次刷新了我对所有区间问题的认识。
    让我觉得问题套路层出不穷,似乎找不着规律。
    很久之前就接触过这题,但是当时并没有太重视。
    虽然知道是二分答案,但是知道是要求区间和为负数时就无从下手。
    明明是很简单的问题,但是就是转不出脑袋里的死胡同。
    心里一心想着分治,因为之前的题目种种显示是所有区间问题可以利用分治、动态规划等来解决。
    然后找不着头绪。
    其实归并排序找逆序对也算是分治。
    但是并没有想出是要找逆序对的个数。
    导致遇到这道题不知所措。
    还是要多练习问题的转化。


    本道题主要思路:
    第k大平均数->二分
    区间平均数小于mid->区间和为负->前缀和的逆序对等同于区间负

  • 相关阅读:
    搭建SSM框架 Demo
    Mybatis (ParameterType) 如何传递多个不同类型的参数
    IDEA如何将本地项目上传到码云
    VUE项目
    Oralce(三)特殊符号
    NodeJS and Intellij IDEA
    Handler
    Netty 框架 (一) channelDisconnected、channelClosed两个事件区别
    数据库索引
    Websocket
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714845.html
Copyright © 2020-2023  润新知