# [JSOI 2011]柠檬

## Description

$1\leq n\leq 100000,1\leq s_i\leq 10000$

## Solution

（其实就是四边形不等式 $w$ 是满足 $\geq$ 的，并且 DP 值取 $\max$。原理戳这

## Code

#include <bits/stdc++.h>
#define ll long long
#define x(a) (s[a])
#define y(a) (-f[a-1]-1ll*t*s[a]*s[a]+2ll*t*s[a])
#define pop pop_back
#define push push_back
using namespace std;
const int N = 100000+5;

int n, l[N], c[N], s[N];
vector<int> S[N];
ll f[N];

int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &c[i]), s[i] = s[l[c[i]]]+1, l[c[i]] = i;
for (int i = 1; i <= n; i++) {
int t = c[i], sz;
while ((sz = S[t].size()) >= 2 &&
(y(S[t][sz-1])-y(i))*(x(S[t][sz-2])-x(i)) <= (y(S[t][sz-2])-y(i))*(x(S[t][sz-1])-x(i))) S[t].pop();
S[t].push(i);
while ((sz = S[t].size()) >= 2 && (y(S[t][sz-1])-y(S[t][sz-2])) >= -2ll*t*s[i]*(x(S[t][sz-1])-x(S[t][sz-2]))) S[t].pop();
f[i] = f[S[t][(sz = S[t].size())-1]-1]+1ll*t*(s[i]-s[S[t][sz-1]]+1)*(s[i]-s[S[t][sz-1]]+1);
}
printf("%lld\n", f[n]);
return 0;
}
posted @ 2020-03-05 17:13  NaVi_Awson  阅读(146)  评论(0编辑  收藏  举报