Codeforces 939E - Maximize!

939E - Maximize!

思路:

贪心:最后的集合是最大值+前k小个

因为平均值时关于k的凹形函数,所以可以用三分求最小值

又因为后面的k肯定比前面的k大,所以又可以双指针

三分:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define pli pair<ll,int>
#define mem(a,b) memset(a,b,sizeof(a))

const int N=5e5+5;
ll sum[N],cnt=0;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout<<fixed<<setprecision(9);
    int q,t,x;
    cin>>q;
    while(q--){
        cin>>t;
        if(t==1){
            cin>>x;
            sum[++cnt]=sum[cnt-1]+x;
        }
        else{
            int l=1,r=cnt-1,m1=(l+l+r)/3,m2=(l+r+r)/3;
            while(l<r){
                if((double)(sum[m1]+x)/(m1+1)>=(double)(sum[m2]+x)/(m2+1)){
                    if(l==m1)break;
                    else l=m1;
                }
                else{
                    if(r==m2)break;
                    else r=m2;
                }
                m1=(l+l+r)/3,m2=(l+r+r)/3;
            }
            double tt=(double)(sum[l]+x)/(l+1);
            for(int i=l;i<=r;i++)tt=min(tt,(double)(sum[i]+x)/(i+1));
            cout<<x-tt<<endl;
        }
    }
    return 0;
}

双指针:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define pli pair<ll,int>
#define mem(a,b) memset(a,b,sizeof(a))

const int N=5e5+5;
ll sum[N],cnt=0,top=0,x;
double cal(int l){
    return (double)(x+sum[l])/(l+1);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout<<fixed<<setprecision(9);
    int q,t;
    cin>>q;
    while(q--){
        cin>>t;
        if(t==1){
            cin>>x;
            sum[++cnt]=sum[cnt-1]+x;
        }
        else{
            while(top<cnt){
                if(cal(top+1)<cal(top))top++;
                else break;
            }
            cout<<x-cal(top)<<endl;
        }
    }
    return 0;
}

 

posted @ 2018-03-02 20:13  Wisdom+.+  阅读(205)  评论(0编辑  收藏  举报