zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:平均数(二分答案+归并排序)

    题目描述

    有一天,小$A$得到了一个长度为$n$的序列。
    他把这个序列的所有连续子序列都列了出来,并对每一个子序列都求了其平均值,然后他把这些平均值写在纸上,并对它们进行排序,最后他报出了第$k$小的平均值。
    你要做的就是模仿他的过程。


    输入格式

    第一行两个整数$n,k$,意义如题中所述。
    第二行$n$个正整数,即为小$A$得到的序列。


    输出格式

    一行一个实数,表示第$k$小的平均值,保留到小数点后$4$位。


    样例

    样例输入:

    6 10
    3 5 4 6 1 2

    样例输出:

    3.6667


    数据范围与提示

    对于$40\%$的数据,$nleqslant 1,000$。
    对于$100\%$的数据,$nleqslant 100,000,kleqslant frac{n imes (n+1)}{2}$,序列中的数$leqslant {10}^9$。


    题解

    对于答案,我们可以二分,那么现在我们考虑如何$judge$。

    我们可以让整个序列都减去我们现在二分的这个答案,然后对其取前缀和,那么如果前缀和上$S_{l-1}>S_r$的化就说明这段的平均值比二分的答案小;而我们现在要求的就是这个前缀和序列的逆序对的数量,可以用归并排序解决。

    精度可能会有问题,建议使用$long double$。

    时间复杂度:$Theta(nlog^2 n)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    const long double eps=1e-5;
    int n;
    long long k;
    long double a[100001],b[100001],que[100001];
    int merge(int l,int r)
    {
    	if(l==r)return 0;
    	int mid=(l+r)>>1;
    	int res=merge(l,mid)+merge(mid+1,r);
    	int lft=l,rht=mid+1,cnt=l-1;
    	while(lft<=mid&&rht<=r)
    	{
    		if(b[rht]<b[lft])
    		{
    			que[++cnt]=b[rht];
    			res+=mid-lft+1;
    			rht++;
    		}
    		else
    		{
    			que[++cnt]=b[lft];
    			lft++;
    		}
    	}
    	while(lft<=mid){que[++cnt]=b[lft];lft++;}
    	while(rht<=r){que[++cnt]=b[rht];rht++;}
    	for(int i=l;i<=r;i++)b[i]=que[i];
    	return res;
    }
    bool judge(long double x)
    {
    	for(int i=1;i<=n;i++)
    		b[i]=a[i]+b[i-1]-x;
    	int res=merge(0,n);
    	return res<k;
    }
    int main()
    {
    	scanf("%d%lld",&n,&k);
    	for(int i=1;i<=n;i++)scanf("%Lf",&a[i]);
    	long double lft=0.0,rht=1000000000.0;
    	while(rht-lft>=eps)
    	{
    		long double mid=0.5*(lft+rht);
    		if(judge(mid))lft=mid;
    		else rht=mid;
    	}
    	printf("%.4Lf",lft);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    169_Majority Element
    171_Excel Sheet Column Number
    217_Contains Duplicate
    242_Valid Anagram
    【findIndex】根据数组对象某一元素的id,找到此元素在数组所在的位置
    【鼠标右击组件】v-contextmenu
    【 拖拽组件】基于 Sortable.js 的 Vue 拖拽组件。 访问地址:Vue.Draggable
    【vue-markdown编辑器】vue-markdown 组件github地址
    mac下如何制作windows启动盘
    【vue webstorm】WebStorm Vue代码格式错误
  • 原文地址:https://www.cnblogs.com/wzc521/p/11597864.html
Copyright © 2011-2022 走看看