绝对不要用宏定义定义二分里的Clac()函数!!!
会爆精度!!!!
函数里一定要加 1ll*
因为这俩原因调了一下午
#include<bits/stdc++.h>
#define N 100005
#define ll unsigned long long
#define f1(i,n,m) for(int i=n;i<=m;++i)
#define f2(i,n,m) for(int i=n;i>=m;--i)
#define min(a,b) a<b? a:b
#define reset(a,b) memset(a,b,sizeof(a))
#define clac(i,j) (dp[j-1]+pow(sum[i]-sum[j]+1,2)*col[i])
#define s(i) (int)q[col[i]].size()-1
#define t1(i) q[col[i]][s(i)]
#define t2(i) q[col[i]][s(i)-1]
using namespace std;
template <typename T>
inline void read(T &x){
int w=1;x=0;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
x*=w;
}
int n;
int col[N],pre[N],sum[N];
ll dp[N];
ll Clac(int i,int j) {return dp[j-1]+1ll*i*i*col[j];}
vector<int>q[N];
inline int bound(int x,int y){
int mid,l=sum[y],r=n+1;
while(l<r){
mid=(l+r)>>1;
Clac(mid-sum[x]+1,x)>=Clac(mid-sum[y]+1,y)?r=mid:l=mid+1;
}
return r;
}
signed main(){
read(n);
f1(i,1,n){
read(col[i]);
sum[i]=sum[pre[col[i]]]+1;
pre[col[i]]=i;
}
f1(i,1,n){
while(s(i)>=1&&bound(t2(i),t1(i))<=bound(t1(i),i))q[col[i]].pop_back();
q[col[i]].push_back(i);
while(s(i)>=1&&clac(i,t2(i))>=clac(i,t1(i)))q[col[i]].pop_back();
dp[i]=clac(i,t1(i));
// cout<<t1(i)<<" ";
}
printf("%lld\n",dp[n]);
return 0;
}
/*
10
2 2 30 2 2 2 30 2 2 2
*/