rt,#4怎么都过不去
//决策单调性优化DP
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
long long f[21][N],L = 1,R = 0,a[N],j,co[N],ans; //f[j][i]将前i个数划分k段
//f[i][j] = min{f[k][j - 1] + cal(k + 1,i)}
inline void add(int x)
{
ans+=co[x];
co[x]++;
}
inline void del(int x)
{
co[x]--;
ans-=co[x];
}
long long cal(int l, int r)
{
while(L > l) add(a[--L]);
while(L < l) del(a[L++]);
while(R > r) del(a[R--]);
while(R < r) add(a[++R]);
return ans;
}
void solve(int ll,int rr,int l,int r) //从上一层转移下来
{
if(l > r) return;
int Min = 0,mid = (l + r)>>1;
long long res = 1e18;
for(int i = ll;i <= rr;i++) //暴力求解mid最优解
{
long long tmp = cal(i + 1,mid);
if(f[j - 1][i] + tmp < res) res = f[j - 1][i] + tmp,Min = i;
}
f[j][mid] = res;
solve(ll,Min,l,mid - 1); //分治
solve(Min,rr,mid + 1,r);
}
int main()
{
memset(f,0x3f,sizeof(f));
int n,k,i;
cin>>n>>k;
for(i = 1;i <= n;i++) cin>>a[i];
f[0][0] = 0;
for(j = 1;j <= k;j++) solve(1,n,1,n); //求解第j层最优解
cout<<f[k][n];
return 0;
}