wannafly 练习赛11 E 求最值(平面最近点对)

链接:https://www.nowcoder.com/acm/contest/59/E

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

给你一个长为n的序列a

定义f(i,j)=(i-j)2+g(i,j)2

g是这样的一个函数

求最小的f(i,j)的值,i!=j


输入描述:

第一行一个数n
之后一行n个数表示序列a

输出描述:

输出一行一个数表示答案
示例1

输入

4
1 0 0 -1

输出

1

备注:

对于100%的数据,2 <= n <= 100000 , |ai| <= 10000

//////////////////////////////////////////////////////////////////////////////////////////////////

用前缀和s[i]做y值,i做x值,问题等价与求平面最近点对之间的距离

放两个找的别人的平面最近点对的证明

https://www.zhihu.com/question/24755395

http://blog.csdn.net/yql_water/article/details/45939653

自己的代码是借鉴后面那个blog的

///////////////////////////////////////////////////////////////////////////////////////////////////

 1 #include <bits/stdc++.h>
 2 #define mst(a,b)    memset((a),(b), sizeof a)
 3 #define lowbit(a)   ((a)&(-a))
 4 #define IOS         ios::sync_with_stdio(0);cin.tie(0);
 5 #define MP          make_pair
 6 #define PB          push_back
 7 using namespace std;
 8 typedef long long ll;
 9 typedef pair<int,int> pii;
10 const ll INF = 0x3f3f3f3f3f3f3f3f;
11 const int mod=1e9+7;
12 const int maxn=1e5+10;
13 struct node{
14     int x,y;
15     bool operator<(const node&p)const{return x<p.x;}
16 }a[maxn];
17 ll dis(int L,int R){
18     return (ll)(a[L].x-a[R].x)*(a[L].x-a[R].x)+(ll)(a[L].y-a[R].y)*(a[L].y-a[R].y);
19 }
20 ll dfs(int L,int R,vector<int>&t){
21     if(R-L<=1){
22         if(R==L){t.PB(L);return INF;}
23         if(a[L].y>a[R].y)t.PB(R),t.PB(L);
24         else t.PB(L),t.PB(R);
25         return dis(L,R);
26     }
27     vector<int>tl,tr;
28     int mid=(L+R)>>1;
29     ll mm=min(dfs(L,mid,tl),dfs(mid+1,R,tr));
30     int i=0,j=0,n=tl.size(),m=tr.size();
31     while(i<n||j<m){
32         if(j>=m||i<n&&a[tl[i]].y<a[tr[j]].y)t.PB(tl[i++]);
33         else t.PB(tr[j++]);
34     }
35     for(i=0;i<t.size();++i)for(j=1;j<7&&j+i<t.size();++j)
36         mm=min(mm,dis(t[i],t[i+j]));
37     return mm;
38 }
39 int main(){
40 #ifdef local
41 freopen("in.txt","r",stdin);
42 //freopen("out.txt","w",stdout);
43 #endif
44     int n;scanf("%d",&n);
45     for(int i=1;i<=n;++i)scanf("%d",&a[i].x),a[i].x+=a[i-1].x,a[i].y=i;
46     sort(a+1,a+1+n);
47     vector<int>t;
48     printf("%lld",dfs(1,n,t));
49     return 0;
50 }

 

posted on 2018-02-23 18:14  scau_bi  阅读(183)  评论(0编辑  收藏  举报

导航