●CodeForces 429D Trick_Function
题链:
http://codeforces.com/problemset/problem/429/D
题解:
分治,最近点对
不难发现g(i,j)=sum[j]-sum[i],
那么f(i,j)=(i-j)²+(sum[j]-sum[i])²
=(i-j)²+(sum[i]-sum[j])²
然后可以把(i,sum[i])看成平面上的点,
那么要求f(i,j)min就转变为了求平面上的最近点对问题。
用分治即可解决。
代码:
#include<bits/stdc++.h>
#define MAXN 100005
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3fll
using namespace std;
struct Point{
ll x,y;
bool operator < (const Point &rtm) const {
return x<rtm.x||(x==rtm.x&&y<rtm.y);
}
}A[MAXN],B[MAXN];
int N;
ll sum[MAXN];
int idx[MAXN];
ll ABS(ll x){return x<0?-x:x;}
bool cmpx(const Point &a,const Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool cmpy(const Point &a,const Point &b){return a.y<b.y||(a.y==b.y&&a.x<b.x);}
ll dis2(Point &a,Point &b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
void build_index(){
map<Point,int>M;
for(int i=1;i<=N;i++) M[A[i]]=i;
for(int i=1;i<=N;i++) idx[i]=M[B[i]];
}
ll divide(int l,int r){
ll ans=INF;
static int tmpidx[MAXN];
static Point tmpB[MAXN];
if(r-l<=3){
for(int i=l;i<=r;i++) for(int j=i+1;j<=r;j++)
ans=min(ans,dis2(A[i],A[j]));
return ans;
}
int mid=(l+r)>>1,bl=l,br=mid+1,bnt;
for(int i=l;i<=r;i++){
if(idx[i]<=mid) tmpB[bl]=B[i],tmpidx[bl++]=idx[i];
else tmpB[br]=B[i],tmpidx[br++]=idx[i];
}
for(int i=l;i<=r;i++) B[i]=tmpB[i],idx[i]=tmpidx[i];
ans=min(ans,divide(l,mid));
ans=min(ans,divide(mid+1,r));
bnt=l; bl=l; br=mid+1;
//归并排序
while(bl<=mid&&br<=r){
if(cmpy(B[bl],B[br])) tmpB[bnt++]=B[bl++];
else tmpB[bnt++]=B[br++];
}
while(bl<=mid) tmpB[bnt++]=B[bl++];
while(br<=r) tmpB[bnt++]=B[br++];
for(int i=l;i<=r;i++) B[i]=tmpB[i];
bnt=1;
for(int i=l;i<=r;i++) if(ABS(B[i].x-A[mid].x)<=ans)
tmpB[bnt++]=B[i];
for(int i=1;i<bnt;i++)
for(int j=1;j<=6&&i+j<bnt;j++)
ans=min(ans,dis2(tmpB[i],tmpB[i+j]));
return ans;
}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%lld",&sum[i]);
sum[i]+=sum[i-1];
A[i]=B[i]=(Point){i,sum[i]};
}
sort(A+1,A+N+1,cmpx);
sort(B+1,B+N+1,cmpy);
build_index();
ll ans=divide(1,N);
printf("%lld\n",ans);
return 0;
}
Do not go gentle into that good night.
Rage, rage against the dying of the light.
————Dylan Thomas

浙公网安备 33010602011771号