【题目链接】

【算法】

令Si = A1 + A2 + ... + Ai（A的前缀和）

则g(i,j) = Sj - Si

f(i,j) = (i-j)^2 + (Si - Sj)^2

观察这个式子，我们发现可以用类似于平面最近点对的算法来求解该问题

【代码】

```#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
const long long INF = 1e15;

int i,n,x;
long long sum[MAXN];

struct point
{
long long x,y;
} a[MAXN];

inline bool cmpx(point a,point b)
{
return a.x < b.x;
}
inline bool cmpy(point a,point b)
{
return a.y < b.y;
}
inline long long dist(point a,point b)
{
return abs(a.x - b.x) * abs(a.x - b.x) + abs(a.y - b.y) * abs(a.y - b.y);
}
inline long long Closest_Pair(int l,int r)
{
int i,j,mid,len = 0;
long long d;
static point s[MAXN];
if (l == r) return INF;
if (l + 1 == r) return dist(a[l],a[r]);
mid = (l + r) >> 1;
d = min(Closest_Pair(l,mid),Closest_Pair(mid+1,r));
for (i = l; i <= r; i++)
{
if ((double)abs(a[i].x - a[mid].x) <= (double)sqrt(d)) s[++len] = a[i];
}
sort(s+1,s+len+1,cmpy);
for (i = 1; i <= len; i++)
{
for (j = i + 1; j <= len && s[j].y - s[i].y <= sqrt(d); j++)
{
d = min(d,dist(s[i],s[j]));
}
}
return d;
}

int main()
{

scanf("%d",&n);
for (i = 1; i <= n; i++)
{
scanf("%d",&x);
sum[i] = sum[i-1] + x;
}
for (i = 1; i <= n; i++) a[i] = (point){i,sum[i]};
sort(a+1,a+n+1,cmpx);
printf("%I64d\n",Closest_Pair(1,n));

return 0;

}```