D. Tricky Function

Time Limit: 20 Sec

Memory Limit: 256 MB

## 题目连接

codeforces.com/problemset/problem/429/D

## Description

Iahub and Sorin are the best competitive programmers in their town. However, they can't both qualify to an important contest. The selection will be made with the help of a single problem. Blatnatalag, a friend of Iahub, managed to get hold of the problem before the contest. Because he wants to make sure Iahub will be the one qualified, he tells Iahub the following task.

You're given an (1-based) array a with n elements. Let's define function f(i, j) (1 ≤ i, j ≤ n) as (i - j)2 + g(i, j)2. Function g is calculated by the following pseudo-code:

int g(int i, int j) {
int sum = 0;
for (int k = min(i, j) + 1; k <= max(i, j); k = k + 1)
sum = sum + a[k];
return sum;
}

Find a value mini ≠ j  f(i, j).

Probably by now Iahub already figured out the solution to this problem. Can you?

Input

The first line of input contains a single integer n (2 ≤ n ≤ 100000). Next line contains n integers a[1], a[2], ..., a[n] ( - 104 ≤ a[i] ≤ 104).

Output

Output a single integer — the value of mini ≠ j  f(i, j).

Sample Input

4
1 0 0 -1

Sample Output

1

## HINT

f(i,j)=(j-i)^2+(sum[j]-sum[i])^2

1.科学的暴力加剪枝

2.最近点对问题

3.对每一个点进行二分  nlogn感觉非常科学

```#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 2000001
#define mod 10007
#define eps 1e-5
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//**************************************************************************************

struct Point
{
ll x;
ll y;
}point[maxn];
int n;
int tmpt[maxn];

bool cmpxy(const Point& a, const Point& b)
{
if (a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}

bool cmpy(const int& a, const int& b)
{
return point[a].y < point[b].y;
}

ll dis2(int i, int j)
{
return (point[i].x - point[j].x) * (point[i].x - point[j].x)
+ (point[i].y - point[j].y) * (point[i].y - point[j].y);
}

ll sqr(ll x)
{
return x * x;
}

ll Closest_Pair(int left, int right)
{
ll d = infll;
if (left == right)
return d;
if (left + 1 == right)
return dis2(left, right);
int mid = (left + right) >> 1;
ll d1 = Closest_Pair(left, mid);
ll d2 = Closest_Pair(mid + 1, right);
d = min(d1, d2);
int i, j, k = 0;
//分离出宽度为d的区间
for (i = left; i <= right; i++) {
if (sqr(point[mid].x - point[i].x) <= d)
tmpt[k++] = i;
}
sort(tmpt, tmpt + k, cmpy);
//线性扫描
for (i = 0; i < k; i++) {
for (j = i + 1; j < k && sqr(point[tmpt[j]].y - point[tmpt[i]].y) < d;
j++) {
ll d3 = dis2(tmpt[i], tmpt[j]);
if (d > d3)
d = d3;
}
}
return d;
}

int main()
{
scanf("%d", &n);
ll sum = 0;
for (int i = 0; i < n; ++i)
{
int x;
scanf("%d", &x);
point[i].x = i;
sum += x;
point[i].y = sum;
}
cout << Closest_Pair(0, n - 1) << endl;
return 0;
}```