• Codeforces Round #464 (Div. 2) E. Maximize!


    题目链接:http://codeforces.com/contest/939/problem/E

    E. Maximize!

    time limit per test3 seconds
    memory limit per test256 megabytes

    Problem Description

    You are given a multiset S consisting of positive integers (initially empty). There are two kind of queries:

    Add a positive integer to S, the newly added integer is not less than any number in it.
    Find a subset s of the set S such that the value is maximum possible. Here max(s) means maximum value of elements in s, — the average value of numbers in s. Output this maximum possible value of .

    Input

    The first line contains a single integer Q (1 ≤ Q ≤ 5·105) — the number of queries.

    Each of the next Q lines contains a description of query. For queries of type 1 two integers 1 and x are given, where x (1 ≤ x ≤ 109) is a number that you should add to S. It’s guaranteed that x is not less than any number in S. For queries of type 2, a single integer 2 is given.

    It’s guaranteed that the first query has type 1, i. e. S is not empty when a query of type 2 comes.

    Output

    Output the answer for each query of the second type in the order these queries are given in input. Each number should be printed in separate line.

    Your answer is considered correct, if each of your answers has absolute or relative error not greater than 10 - 6.

    Formally, let your answer be a, and the jury’s answer be b. Your answer is considered correct if .

    Examples

    input
    6
    1 3
    2
    1 4
    2
    1 8
    2
    output
    0.0000000000
    0.5000000000
    3.0000000000
    input
    4
    1 1
    1 4
    1 5
    2
    output
    2.0000000000


    解题心得:

    1. 题意就是给你n次询问,每次有两种情况,第一种,在一个集合中插入一个不小于集合中任意数的数,第二种就是在集合中选一个子集出来,要求子集的最大值减去子集的平均值最大,输出这个最大值。
    2. 首先有个贪心的思想,要想最大值减去平均值最大,那么最大值要尽可能的大(尝试一下会发现符合要求的子集中必然包含最大值,也比较容易想明白),然后要平均值尽可能的小,那么假设先选一个子集出来,算出平均值,如果集合中还有比平均值更小的数,那么必然可以将这个数加入子集中拉小平均值。
    3. 因为插入的数是越来越大的,所以形成的数列是升序,那么在找最小的平均值的时候就可以二分查找,先求出前缀和,每次寻找一个点,看这个点的前缀和算出的平均值是否比下一个数更大。以此来进行二分查找。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6;
    
    ll sum[maxn];
    vector <int> ve;
    int n;
    
    void get_ans(){
        int l = 0,r = ve.size()-2,mid;
        double ave;//平均值
        while(l < r){
            mid = (l + r)/2;
            ave = (double )(ve[ve.size()-1] + sum[mid])/(double )(mid+2);
            if(ave > ve[mid+1])
                l = mid+1;
            else
                r = mid;
        }
        ave = (double)(sum[l]+ve[ve.size()-1])/(l+2);
        double ans = ve[ve.size()-1] - ave;
        printf("%.9f
    ",ans);//注意一下精度问题
    }
    
    int main(){
        scanf("%d",&n);
        while(n--){
            int a,b;
            scanf("%d",&a);
            if(a == 1){
                scanf("%d",&b);
                ve.push_back(b);
                sum[ve.size()-1] = sum[ve.size()-2]+b;//得出前缀和
            }
            else
                get_ans();
        }
        return 0;
    }
  • 相关阅读:
    [转]Angular4首页加载慢优化之路
    [转]angular 禁止缓存
    微服务之分布式跟踪系统(springboot+pinpoint)
    分布式追踪系统设计与实现
    QLExpress 规则引擎使用介绍
    几个常见规则引擎的简单介绍和演示
    大数据对账
    美团配送资金安全治理之对账体系建设
    美的支付-对账系统实现
    redis实现对账(集合比较)功能
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107166.html
Copyright © 2020-2023  润新知