【Codeforces 429D】 Tricky Function

【题目链接】

           http://codeforces.com/problemset/problem/429/D

【算法】

           令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;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9241172.html