Article From:https://www.cnblogs.com/dream-maker-yk/p/9732656.html

Description

Flute I like lemon very much. It prepares a bunch of shells that are strung together with branches, and intends to use a magic trick to turn shells into lemons. Shells have N (1 or less than N or less than 100000) only, and they are arranged on the branches in sequence. For convenience, we shell 1..N from left to right. Each shellThe size of shells is not the same. The size of shell I is Si (1 Si or less than 10000). The magic of changing lemons requires Flute to take a small piece of continuous shells from one end of the branch at a time and select a shell size s0. If the shell is small in sizeThe shell of S0 has t, so magic can turn this little shell into s0t^2 lemon. Flute can take shells for many times until the shells on the branches are all taken away. In each segment, the shell size S0 selected by Flute can be different. In the endThe number of lemons obtained by Flute is the sum of all small segments of lemon. Flute wants to know how much lemon it can produce with the shellfish. Please help solve this problem.

Input

The first line: an integer indicating N.
Second. N + 1 rows: one integer for each row, and I + 1 row for Si.

Output

There is only one integer representing the maximum number of lemons that Flute can get.

Sample Input

5
2
2
5
2
3

Sample Output

21
//Flute First take 4 shells from the left side, their size is 2, 2, 5, 2. Choose S0 = 2, and there are three shells the size of S0 in this section. By magic, you can get 2 x 3 ^ 2 = 18 lemons. Then take the last shell from the right side.By magic, you can get 1 x 3^1 = 3 lemons. A total of 18 + 3 = 21 lemon. There is no better plan than this.


\(j_1<j_2<i_1<i_2\)
Because each type of prefix is monotonically increasing.\(y=x^2\)It is a convex function, so if\(i_1\)place\(j_1\)than\(j_2\)Better, there is\(i_2\)Time\(j_1\)Certain ratio\(j_2\)excellent
So you can maintain a monotonous stack for each category.
This will maintain the best decision points.
But in order to ensure that the decision and slope are monotonous, before joining the node, we can judge that if the minimum prefix size of stack top-1 over stack top is less than or equal to the minimum prefix size of the station top over the current node, then stack top is invalid.
Then after adding the stack top – 1 over the stack top prefix size is less than or equal to the current minimum prefix, then the stack top is no longer excellent, just pop the stack


//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define for_up(a, b, c) for (int a = b; a <= c; ++a)
#define for_down(a, b, c) for (int a = b; a >= c; --a)
#define for_vector(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
  bool w = 1;x = 0;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') w = 0, c = getchar();
  while (isdigit(c)) {
    x = (x<<1) + (x<<3) + c -'0';
    c = getchar();
  }
  if (!w) x = -x;
}
template <typename T>
void Write(T x) {
  if (x < 0) {
    putchar('-');
    x = -x; 
  }
  if (x > 9) Write(x / 10);
  putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 1e5 + 10;
const int M = 1e4 + 10;
ll dp[N];
int n, a[N];
int pre[N], last[N], s[N];
vector<int> p[M];
ll cal(int lastpos, int vl) {
  return dp[lastpos - 1] + 1ll * a[lastpos] * vl * vl;
}
int check(int x, int y) { // Calculate the minimum prefix of X point over Y point.Int l = 1, r = n, ans = n + 1;While (L < = R) {Int mid = (L + R) > >1;If (CAL (x, mid - s[x] + 1) > = cal (y, mid s[y] + 1)) = = ans, = = 1;Else L =Mid + 1;}Return ans;}#define S (s) (signed) s.size ()#define R1 (s) S (s) - 1#define R2 (s) S (s)) - 2#define now p[a[i]]Int main () {Read (n);For_up (I, 1, n) {Read (a[i]);Last[i] =Pre[a[i]];S[i] = s[last[i]] + 1;Pre[a[i]] = I;}For_up (I, 1, n) {While (S (now) ≫ 1 & & check (now[R2 (now)], now[R1 (now)] < = check (now[R1 (<)], ()) (());Now.push_back (I);While (S (now) > 1 & & check (now[R2 (now)], now[R1 (now)]); (= =)Now.pop_back ();Dp[i] = cal (now[R1 (now)], s[i] s[now[R1 (now)]] + 1ll;}Write (dp[n]);Return 0;}

Leave a Reply

Your email address will not be published. Required fields are marked *