• 【CF660F】Bear and Bowling 4


    题目

    题目链接:https://codeforces.com/problemset/problem/660/F
    给一个长度为 (n) 的序列 (a),选一个区间 ([l,r]) 使得 (sum^{r}_{i=l}(i-l+1) imes a_i) 最大。
    (nleq 2 imes 10^5)

    思路

    (f_i)(a) 的前缀和,(g_i=sum^{i}_{j=1}j imes a_j)。那么

    [ans_j=max_{0leq i<j}(g_j-g_i-i imes (f_j-f_i)) ]

    维护一个上突壳,二分斜率即可。
    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=200010;
    int n,top,q[N];
    ll ans,f[N],g[N],X[N],Y[N];
    
    double slope(int i,int j)
    {
    	return 1.0*(Y[i]-Y[j])/(X[i]-X[j]);
    }
    
    int binary(double k)
    {
    	int l=2,r=top,mid;
    	while (l<=r)
    	{
    		mid=(l+r)>>1;
    		if (slope(q[mid],q[mid-1])>=k) l=mid+1;
    			else r=mid-1;
    	}
    	return q[l-1];
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1,x;i<=n;i++)
    	{
    		scanf("%d",&x);
    		f[i]=f[i-1]+x; g[i]=g[i-1]+1LL*x*i;
    		X[i]=i; Y[i]=1LL*i*f[i]-g[i];
    	}
    	q[++top]=0;
    	for (int i=1;i<=n;i++)
    	{
    		int j=binary(f[i]);
    		ans=max(ans,g[i]-g[j]-1LL*j*(f[i]-f[j]));
    		while (top>1 && slope(q[top-1],q[top])<=slope(q[top],i)) top--;
    		q[++top]=i;
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Marriage Match II 【HDU
    Leapin' Lizards [HDU
    稳定婚姻匹配问题
    Sabotage 【UVA
    动态树 学习
    Minimum Cost 【POJ
    Colourful Rectangle【扫描线】
    Get The Treasury【HDU-3642】【扫描线】
    Picture【HDU
    洛谷P1457 城堡 The Castle
  • 原文地址:https://www.cnblogs.com/stoorz/p/15509281.html
Copyright © 2020-2023  润新知