Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <stdio.h>
- #include <stack>
- #include <vector>
- #include <algorithm>
- using namespace std;
- #define pb push_back
- #define mp make_pair
- typedef long long ll;
- typedef long double ld;
- #define sz(v) (int)v.size()
- ll INF = 1ll << 50;
- const int N = 1000002;
- int t,n;
- ll a,b,c,x[N],dp[N],A[N];
- ll k1[N],b1[N];
- /////////////////////// convex hull trick: begin
- struct line{
- ll k,b;
- ll xs;
- line(ll k1, ll b1){
- k = k1;
- b = b1;
- xs = -INF;
- }
- };
- struct chull{
- vector <line> v;
- void add(ll k, ll b){
- line L(k,b);
- while(!v.empty()){
- line R = v.back();
- ll x = ((R.b - L.b) + (L.k - R.k) - 1)/(L.k - R.k);
- if(x <= R.xs) v.pop_back();
- else {L.xs = x; break;}
- }
- v.push_back(L);
- }
- ll get(ll x){
- int B = 0, E = sz(v)-1;
- while(B!=E){
- int M = (B+E+1)/2;
- if(v[M].xs > x) E = M-1;
- else B = M;
- }
- return x*v[B].k + v[B].b;
- }
- };
- /////////////////////// convex hull trick: end
- int main(){
- scanf("%d", &t);
- while(t){
- t--;
- scanf("%d", &n);
- scanf("%lld%lld%lld", &a, &b, &c);
- chull st;
- for(int i=1;i<=n;i++){
- scanf("%lld", &x[i]);
- A[i] = A[i-1] + x[i];
- k1[i] = -2*a*A[i];
- }
- dp[1] = a*x[1]*x[1] + b*x[1] + c;
- b1[1] = dp[1] + a*A[1]*A[1] - b*A[1];
- st.add(k1[1], b1[1]);
- for(int i=2;i<=n;i++){
- dp[i] = a*A[i]*A[i] + b*A[i] + c + st.get(A[i]);
- dp[i] = max(dp[i],a*A[i]*A[i] + b*A[i] + c);
- b1[i] = dp[i] + a*A[i]*A[i] - b*A[i];
- st.add(k1[i], b1[i]);
- }
- printf("%lld\n", dp[n]);
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment