wannafly 练习赛11 E 求最值(平面最近点对)
链接:https://www.nowcoder.com/acm/contest/59/E
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
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 }