#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
struct node{
ll x,y;
bool operator<(const node&n)const {
return x < n.x;
}
};
node a[maxn],c[maxn],tmp[maxn];
node Ltmp[maxn],Rtmp[maxn];
ll v[maxn],sum[maxn];
int lcnt, rcnt;
ll dis(node A, node B) {
return (A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y);
}
void merge(int L, int mid, int R) {
lcnt = 0;
int i = L, j = mid + 1;
while(i <= mid && j <= R) {
if(a[i].y != a[j].y ? a[i].y < a[j].y : a[i].x < a[j].x) {
tmp[++ lcnt] = a[i];
i ++;
}else {
tmp[++ lcnt] = a[j];
j ++;
}
}
while(i <= mid) {
tmp[++ lcnt] = a[i];
i ++;
}
while(j <= R) {
tmp[++ lcnt] = a[j];
j ++;
}
for(int i = 1; i <= lcnt; i ++) {
a[L + i - 1] = tmp[i];
}
}
ll find(int l, int r) {
if(l >= r) return 1e18;
int mid = (l + r) >> 1;
ll midx = a[mid].x;
ll D = min(find(l,mid), find(mid+1,r));
lcnt = 0;
for(int i = l; i <= mid; i ++) {
if((midx - a[i].x)*(midx - a[i].x) <= D) {
Ltmp[++ lcnt] = a[i];
}
}
rcnt = 0;
for(int i = mid+1; i <= r; i ++) {
if((a[i].x - midx)*(a[i].x - midx) <= D) {
Rtmp[++ rcnt] = a[i];
}
}
int lpos = 1, rpos = 0;
for(int i = 1; i <= lcnt; i ++) {
while(rpos < rcnt &&
(Rtmp[rpos + 1].y < Ltmp[i].y || (Rtmp[rpos + 1].y - Ltmp[i].y)*(Rtmp[rpos+1].y - Ltmp[i].y) <= D)) {
rpos ++;
}
while(lpos < rcnt && Rtmp[lpos].y < Ltmp[i].y && (Ltmp[i].y - Rtmp[lpos].y)*(Ltmp[i].y - Rtmp[lpos].y) > D) {
lpos ++;
}
for(int j = lpos; j <= rpos; j ++) {
D = min(D, dis(Ltmp[i],Rtmp[j]));
}
}
merge(l, mid, r);
return D;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
cin >> n;
n ++;
a[1].x = -1;
a[1].y = 0;
for (int i = 2; i <= n; i++) {
cin >> v[i];
sum[i] = sum[i-1] + v[i];
a[i].x = i-2;
a[i].y = sum[i];
}
sort(a+1,a+1+n);
cout << find(1,n) << '\n';
}
平面最近点对
最新推荐文章于 2024-07-14 19:56:17 发布