The Official Editorial uses a divide and conquer approach. However, like many divide and conquer optimization problems, this can also be solved using the convex hull trick.
First, define the following:
pre[i]=i=1∑iai
ips[i]=i=1∑iai⋅i
We would like to find the score of some subarray [l,r], defined as
i=l∑rai⋅(i−l+1)
By expanding this expression, we can express this in terms of pre and ips:
For this problem, we need to choose a contiguous subarray in order to maximize the required score. Let us define a function f, such that f(r) denotes the maximum score of a subarray that ends at r. We can thus define f as follows:
We rearrange the equation such that terms that depend only on l are wrapped in parenthesis inside of the max statement and terms that depend only on r are moved outside of the max statement. Note that there is only a single term that depends on both l and r.
Because of this property, we can use the convex hull trick. Each value can be represented as a linear function of the form
gl(x)=l⋅x+(ips[l−1]−pre[l−1]+l⋅pre[l−1])
The original equation can thus be expressed as:
f(r)=1≤l≤rmax{gl(pre[r])}+ips[r]+pre[r]
Implementation
C++
Complexity: O(nlogn). The implementation below uses a Line Container, but it's also possible to dynamically maintain a deque and using binary search for queries by taking advantange of the monotonicity of l.
#include<bits/stdc++.h>
usingnamespace std;
Code Snippet: Line Container (Click to expand)
constint MAXN =2e5+1;
int N;
longlong A[MAXN], pre[MAXN], ips[MAXN];
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!